[Python-checkins] cpython: Use identifier API for PyObject_GetAttrString.

martin.v.loewis python-checkins at python.org
Mon Oct 10 18:11:39 CEST 2011


http://hg.python.org/cpython/rev/81380082d216
changeset:   72848:81380082d216
user:        Martin v. Löwis <martin at v.loewis.de>
date:        Mon Oct 10 18:11:30 2011 +0200
summary:
  Use identifier API for PyObject_GetAttrString.

files:
  Modules/_collectionsmodule.c |    3 +-
  Modules/_csv.c               |    3 +-
  Modules/_datetimemodule.c    |    6 +-
  Modules/_json.c              |    1 +
  Modules/_pickle.c            |   36 +-
  Modules/arraymodule.c        |    8 +-
  Modules/parsermodule.c       |   11 +-
  Modules/posixmodule.c        |    3 +-
  Modules/pyexpat.c            |    4 +-
  Modules/zipimport.c          |    5 +-
  Objects/bytearrayobject.c    |    4 +-
  Objects/classobject.c        |    8 +-
  Objects/descrobject.c        |    3 +-
  Objects/fileobject.c         |   10 +-
  Objects/moduleobject.c       |    3 +-
  Objects/setobject.c          |    3 +-
  Objects/typeobject.c         |   37 +-
  Objects/weakrefobject.c      |    3 +-
  Parser/asdl_c.py             |   24 +-
  Parser/tokenizer.c           |    3 +-
  Python/Python-ast.c          |  601 ++++++++++++----------
  Python/_warnings.c           |    3 +-
  Python/bltinmodule.c         |   14 +-
  Python/codecs.c              |    6 +-
  Python/errors.c              |    3 +-
  Python/import.c              |   16 +-
  Python/pythonrun.c           |   30 +-
  Python/sysmodule.c           |    9 +-
  28 files changed, 501 insertions(+), 359 deletions(-)


diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -767,8 +767,9 @@
 deque_reduce(dequeobject *deque)
 {
     PyObject *dict, *result, *aslist;
+    _Py_identifier(__dict__);
 
-    dict = PyObject_GetAttrString((PyObject *)deque, "__dict__");
+    dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__);
     if (dict == NULL)
         PyErr_Clear();
     aslist = PySequence_List((PyObject *)deque);
diff --git a/Modules/_csv.c b/Modules/_csv.c
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -1317,6 +1317,7 @@
 {
     PyObject * output_file, * dialect = NULL;
     WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
+    _Py_identifier(write);
 
     if (!self)
         return NULL;
@@ -1333,7 +1334,7 @@
         Py_DECREF(self);
         return NULL;
     }
-    self->writeline = PyObject_GetAttrString(output_file, "write");
+    self->writeline = _PyObject_GetAttrId(output_file, &PyId_write);
     if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
         PyErr_SetString(PyExc_TypeError,
                         "argument 1 must have a \"write\" method");
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -3077,12 +3077,14 @@
 {
     PyObject *args, *state, *tmp;
     PyObject *getinitargs, *getstate;
+    _Py_identifier(__getinitargs__);
+    _Py_identifier(__getstate__);
 
     tmp = PyTuple_New(0);
     if (tmp == NULL)
         return NULL;
 
-    getinitargs = PyObject_GetAttrString(self, "__getinitargs__");
+    getinitargs = _PyObject_GetAttrId(self, &PyId___getinitargs__);
     if (getinitargs != NULL) {
         args = PyObject_CallObject(getinitargs, tmp);
         Py_DECREF(getinitargs);
@@ -3097,7 +3099,7 @@
         Py_INCREF(args);
     }
 
-    getstate = PyObject_GetAttrString(self, "__getstate__");
+    getstate = _PyObject_GetAttrId(self, &PyId___getstate__);
     if (getstate != NULL) {
         state = PyObject_CallObject(getstate, tmp);
         Py_DECREF(getstate);
diff --git a/Modules/_json.c b/Modules/_json.c
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -1126,6 +1126,7 @@
     PyObject *ctx;
     static char *kwlist[] = {"context", NULL};
     PyScannerObject *s;
+    _Py_identifier(strict);
 
     assert(PyScanner_Check(self));
     s = (PyScannerObject *)self;
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -826,8 +826,9 @@
 static int
 _Pickler_SetOutputStream(PicklerObject *self, PyObject *file)
 {
+    _Py_identifier(write);
     assert(file != NULL);
-    self->write = PyObject_GetAttrString(file, "write");
+    self->write = _PyObject_GetAttrId(file, &PyId_write);
     if (self->write == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_SetString(PyExc_TypeError,
@@ -1173,15 +1174,19 @@
 static int
 _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
 {
-    self->peek = PyObject_GetAttrString(file, "peek");
+    _Py_identifier(peek);
+    _Py_identifier(read);
+    _Py_identifier(readline);
+
+    self->peek = _PyObject_GetAttrId(file, &PyId_peek);
     if (self->peek == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_Clear();
         else
             return -1;
     }
-    self->read = PyObject_GetAttrString(file, "read");
-    self->readline = PyObject_GetAttrString(file, "readline");
+    self->read = _PyObject_GetAttrId(file, &PyId_read);
+    self->readline = _PyObject_GetAttrId(file, &PyId_readline);
     if (self->readline == NULL || self->read == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_SetString(PyExc_TypeError,
@@ -3390,6 +3395,7 @@
     PyObject *file;
     PyObject *proto_obj = NULL;
     PyObject *fix_imports = Py_True;
+    _Py_identifier(persistent_id);
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:Pickler",
                                      kwlist, &file, &proto_obj, &fix_imports))
@@ -3425,9 +3431,9 @@
     self->fast_nesting = 0;
     self->fast_memo = NULL;
     self->pers_func = NULL;
-    if (PyObject_HasAttrString((PyObject *)self, "persistent_id")) {
-        self->pers_func = PyObject_GetAttrString((PyObject *)self,
-                                                 "persistent_id");
+    if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_id)) {
+        self->pers_func = _PyObject_GetAttrId((PyObject *)self,
+                                              &PyId_persistent_id);
         if (self->pers_func == NULL)
             return -1;
     }
@@ -4935,8 +4941,9 @@
     }
     else {
         PyObject *append_func;
-
-        append_func = PyObject_GetAttrString(list, "append");
+        _Py_identifier(append);
+
+        append_func = _PyObject_GetAttrId(list, &PyId_append);
         if (append_func == NULL)
             return -1;
         for (i = x; i < len; i++) {
@@ -5023,6 +5030,7 @@
     PyObject *state, *inst, *slotstate;
     PyObject *setstate;
     int status = 0;
+    _Py_identifier(__setstate__);
 
     /* Stack is ... instance, state.  We want to leave instance at
      * the stack top, possibly mutated via instance.__setstate__(state).
@@ -5036,7 +5044,7 @@
 
     inst = self->stack->data[Py_SIZE(self->stack) - 1];
 
-    setstate = PyObject_GetAttrString(inst, "__setstate__");
+    setstate = _PyObject_GetAttrId(inst, &PyId___setstate__);
     if (setstate == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_Clear();
@@ -5079,12 +5087,13 @@
         PyObject *dict;
         PyObject *d_key, *d_value;
         Py_ssize_t i;
+        _Py_identifier(__dict__);
 
         if (!PyDict_Check(state)) {
             PyErr_SetString(UnpicklingError, "state is not a dictionary");
             goto error;
         }
-        dict = PyObject_GetAttrString(inst, "__dict__");
+        dict = _PyObject_GetAttrId(inst, &PyId___dict__);
         if (dict == NULL)
             goto error;
 
@@ -5584,8 +5593,9 @@
         return -1;
 
     if (PyObject_HasAttrString((PyObject *)self, "persistent_load")) {
-        self->pers_func = PyObject_GetAttrString((PyObject *)self,
-                                                 "persistent_load");
+        _Py_identifier(persistent_load);
+        self->pers_func = _PyObject_GetAttrId((PyObject *)self,
+                                              &PyId_persistent_load);
         if (self->pers_func == NULL)
             return -1;
     }
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -2003,14 +2003,16 @@
     int mformat_code;
     static PyObject *array_reconstructor = NULL;
     long protocol;
+    _Py_identifier(_array_reconstructor);
+    _Py_identifier(__dict__);
 
     if (array_reconstructor == NULL) {
         PyObject *array_module = PyImport_ImportModule("array");
         if (array_module == NULL)
             return NULL;
-        array_reconstructor = PyObject_GetAttrString(
+        array_reconstructor = _PyObject_GetAttrId(
             array_module,
-            "_array_reconstructor");
+            &PyId__array_reconstructor);
         Py_DECREF(array_module);
         if (array_reconstructor == NULL)
             return NULL;
@@ -2025,7 +2027,7 @@
     if (protocol == -1 && PyErr_Occurred())
         return NULL;
 
-    dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
+    dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__);
     if (dict == NULL) {
         if (!PyErr_ExceptionMatches(PyExc_AttributeError))
             return NULL;
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -3241,10 +3241,13 @@
     copyreg = PyImport_ImportModuleNoBlock("copyreg");
     if (copyreg != NULL) {
         PyObject *func, *pickler;
-
-        func = PyObject_GetAttrString(copyreg, "pickle");
-        pickle_constructor = PyObject_GetAttrString(module, "sequence2st");
-        pickler = PyObject_GetAttrString(module, "_pickler");
+        _Py_identifier(pickle);
+        _Py_identifier(sequence2st);
+        _Py_identifier(_pickler);
+
+        func = _PyObject_GetAttrId(copyreg, &PyId_pickle);
+        pickle_constructor = _PyObject_GetAttrId(module, &PyId_sequence2st);
+        pickler = _PyObject_GetAttrId(module, &PyId__pickler);
         Py_XINCREF(pickle_constructor);
         if ((func != NULL) && (pickle_constructor != NULL)
             && (pickler != NULL)) {
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6103,6 +6103,7 @@
 {
     PyObject *result;
     static PyObject *struct_rusage;
+    _Py_identifier(struct_rusage);
 
     if (pid == -1)
         return posix_error();
@@ -6111,7 +6112,7 @@
         PyObject *m = PyImport_ImportModuleNoBlock("resource");
         if (m == NULL)
             return NULL;
-        struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
+        struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
         Py_DECREF(m);
         if (struct_rusage == NULL)
             return NULL;
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -843,9 +843,9 @@
 {
     int rv = 1;
     PyObject *readmethod = NULL;
+    _Py_identifier(read);
 
-
-    readmethod = PyObject_GetAttrString(f, "read");
+    readmethod = _PyObject_GetAttrId(f, &PyId_read);
     if (readmethod == NULL) {
         PyErr_SetString(PyExc_TypeError,
                         "argument must have 'read' attribute");
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -908,6 +908,7 @@
     static int importing_zlib = 0;
     PyObject *zlib;
     PyObject *decompress;
+    _Py_identifier(decompress);
 
     if (importing_zlib != 0)
         /* Someone has a zlib.py[co] in their Zip file;
@@ -917,8 +918,8 @@
     zlib = PyImport_ImportModuleNoBlock("zlib");
     importing_zlib = 0;
     if (zlib != NULL) {
-        decompress = PyObject_GetAttrString(zlib,
-                                            "decompress");
+        decompress = _PyObject_GetAttrId(zlib,
+                                         &PyId_decompress);
         Py_DECREF(zlib);
     }
     else {
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -2699,13 +2699,15 @@
 bytearray_reduce(PyByteArrayObject *self)
 {
     PyObject *latin1, *dict;
+    _Py_identifier(__dict__);
+
     if (self->ob_bytes)
         latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
                                         Py_SIZE(self), NULL);
     else
         latin1 = PyUnicode_FromString("");
 
-    dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
+    dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
     if (dict == NULL) {
         PyErr_Clear();
         dict = Py_None;
diff --git a/Objects/classobject.c b/Objects/classobject.c
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -14,6 +14,8 @@
 #define PyMethod_MAXFREELIST 256
 #endif
 
+_Py_identifier(__name__);
+
 PyObject *
 PyMethod_Function(PyObject *im)
 {
@@ -226,7 +228,7 @@
         return NULL;
     }
 
-    funcname = PyObject_GetAttrString(func, "__name__");
+    funcname = _PyObject_GetAttrId(func, &PyId___name__);
     if (funcname == NULL) {
         if (!PyErr_ExceptionMatches(PyExc_AttributeError))
             return NULL;
@@ -240,7 +242,7 @@
     if (klass == NULL)
         klassname = NULL;
     else {
-        klassname = PyObject_GetAttrString(klass, "__name__");
+        klassname = _PyObject_GetAttrId(klass, &PyId___name__);
         if (klassname == NULL) {
             if (!PyErr_ExceptionMatches(PyExc_AttributeError))
                 return NULL;
@@ -542,7 +544,7 @@
         return NULL;
     }
 
-    funcname = PyObject_GetAttrString(func, "__name__");
+    funcname = _PyObject_GetAttrId(func, &PyId___name__);
     if (funcname == NULL) {
         if (!PyErr_ExceptionMatches(PyExc_AttributeError))
             return NULL;
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1299,7 +1299,8 @@
 
     /* if no docstring given and the getter has one, use that one */
     if ((doc == NULL || doc == Py_None) && get != NULL) {
-        PyObject *get_doc = PyObject_GetAttrString(get, "__doc__");
+        _Py_identifier(__doc__);
+        PyObject *get_doc = _PyObject_GetAttrId(get, &PyId___doc__);
         if (get_doc) {
             if (Py_TYPE(self) == &PyProperty_Type) {
                 Py_XDECREF(prop->prop_doc);
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -59,8 +59,9 @@
     {
         PyObject *reader;
         PyObject *args;
+        _Py_identifier(readline);
 
-        reader = PyObject_GetAttrString(f, "readline");
+        reader = _PyObject_GetAttrId(f, &PyId_readline);
         if (reader == NULL)
             return NULL;
         if (n <= 0)
@@ -127,11 +128,13 @@
 PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
 {
     PyObject *writer, *value, *args, *result;
+    _Py_identifier(write);
+
     if (f == NULL) {
         PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
         return -1;
     }
-    writer = PyObject_GetAttrString(f, "write");
+    writer = _PyObject_GetAttrId(f, &PyId_write);
     if (writer == NULL)
         return -1;
     if (flags & Py_PRINT_RAW) {
@@ -194,11 +197,12 @@
 {
     int fd;
     PyObject *meth;
+    _Py_identifier(fileno);
 
     if (PyLong_Check(o)) {
         fd = PyLong_AsLong(o);
     }
-    else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
+    else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
     {
         PyObject *fno = PyEval_CallObject(meth, NULL);
         Py_DECREF(meth);
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -415,8 +415,9 @@
 static PyObject *
 module_dir(PyObject *self, PyObject *args)
 {
+    _Py_identifier(__dict__);
     PyObject *result = NULL;
-    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
 
     if (dict != NULL) {
         if (PyDict_Check(dict))
diff --git a/Objects/setobject.c b/Objects/setobject.c
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1933,6 +1933,7 @@
 set_reduce(PySetObject *so)
 {
     PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
+    _Py_identifier(__dict__);
 
     keys = PySequence_List((PyObject *)so);
     if (keys == NULL)
@@ -1940,7 +1941,7 @@
     args = PyTuple_Pack(1, keys);
     if (args == NULL)
         goto done;
-    dict = PyObject_GetAttrString((PyObject *)so, "__dict__");
+    dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
     if (dict == NULL) {
         PyErr_Clear();
         dict = Py_None;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -35,6 +35,9 @@
 static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
 static unsigned int next_version_tag = 0;
 
+_Py_identifier(__dict__);
+_Py_identifier(__class__);
+
 unsigned int
 PyType_ClearCache(void)
 {
@@ -1281,7 +1284,8 @@
 static PyObject *
 class_name(PyObject *cls)
 {
-    PyObject *name = PyObject_GetAttrString(cls, "__name__");
+    _Py_identifier(__name__);
+    PyObject *name = _PyObject_GetAttrId(cls, &PyId___name__);
     if (name == NULL) {
         PyErr_Clear();
         Py_XDECREF(name);
@@ -1709,15 +1713,14 @@
 static PyObject *
 get_dict_descriptor(PyTypeObject *type)
 {
-    static PyObject *dict_str;
+    PyObject *dict_str;
     PyObject *descr;
 
-    if (dict_str == NULL) {
-        dict_str = PyUnicode_InternFromString("__dict__");
-        if (dict_str == NULL)
-            return NULL;
-    }
+    dict_str = _PyUnicode_FromId(&PyId___dict__);
+    if (dict_str == NULL)
+        return NULL;
     descr = _PyType_Lookup(type, dict_str);
+    Py_DECREF(dict_str);
     if (descr == NULL || !PyDescr_IsData(descr))
         return NULL;
 
@@ -2596,12 +2599,13 @@
 {
     PyObject *classdict;
     PyObject *bases;
+    _Py_identifier(__bases__);
 
     assert(PyDict_Check(dict));
     assert(aclass);
 
     /* Merge in the type's dict (if any). */
-    classdict = PyObject_GetAttrString(aclass, "__dict__");
+    classdict = _PyObject_GetAttrId(aclass, &PyId___dict__);
     if (classdict == NULL)
         PyErr_Clear();
     else {
@@ -2612,7 +2616,7 @@
     }
 
     /* Recursively merge in the base types' (if any) dicts. */
-    bases = PyObject_GetAttrString(aclass, "__bases__");
+    bases = _PyObject_GetAttrId(aclass, &PyId___bases__);
     if (bases == NULL)
         PyErr_Clear();
     else {
@@ -3540,7 +3544,7 @@
     PyObject *itsclass = NULL;
 
     /* Get __dict__ (which may or may not be a real dict...) */
-    dict = PyObject_GetAttrString(self, "__dict__");
+    dict = _PyObject_GetAttrId(self, &PyId___dict__);
     if (dict == NULL) {
         PyErr_Clear();
         dict = PyDict_New();
@@ -3560,7 +3564,7 @@
         goto error;
 
     /* Merge in attrs reachable from its class. */
-    itsclass = PyObject_GetAttrString(self, "__class__");
+    itsclass = _PyObject_GetAttrId(self, &PyId___class__);
     if (itsclass == NULL)
         /* XXX(tomer): Perhaps fall back to obj->ob_type if no
                        __class__ exists? */
@@ -6304,16 +6308,15 @@
     }
     else {
         /* Try the slow way */
-        static PyObject *class_str = NULL;
+        PyObject *class_str = NULL;
         PyObject *class_attr;
 
-        if (class_str == NULL) {
-            class_str = PyUnicode_FromString("__class__");
-            if (class_str == NULL)
-                return NULL;
-        }
+        class_str = _PyUnicode_FromId(&PyId___class__);
+        if (class_str == NULL)
+            return NULL;
 
         class_attr = PyObject_GetAttr(obj, class_str);
+        Py_DECREF(class_str);
 
         if (class_attr != NULL &&
             PyType_Check(class_attr) &&
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -157,11 +157,12 @@
 weakref_repr(PyWeakReference *self)
 {
     PyObject *name, *repr;
+    _Py_identifier(__name__);
 
     if (PyWeakref_GET_OBJECT(self) == Py_None)
         return PyUnicode_FromFormat("<weakref at %p; dead>", self);
 
-    name = PyObject_GetAttrString(PyWeakref_GET_OBJECT(self), "__name__");
+    name = _PyObject_GetAttrId(PyWeakref_GET_OBJECT(self), &PyId___name__);
     if (name == NULL || !PyUnicode_Check(name)) {
         if (name == NULL)
             PyErr_Clear();
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -85,8 +85,16 @@
 
     def __init__(self, file):
         self.file = file
+        self.identifiers = set()
         super(EmitVisitor, self).__init__()
 
+    def emit_identifier(self, name):
+        name = str(name)
+        if name in self.identifiers:
+            return
+        self.emit("_Py_identifier(%s);" % name, 0)
+        self.identifiers.add(name)
+
     def emit(self, s, depth, reflow=True):
         # XXX reflow long lines?
         if reflow:
@@ -486,12 +494,12 @@
 
     def visitField(self, field, name, sum=None, prod=None, depth=0):
         ctype = get_c_type(field.type)
-        self.emit("if (PyObject_HasAttrString(obj, \"%s\")) {" % field.name, depth)
+        self.emit("if (_PyObject_HasAttrId(obj, &PyId_%s)) {" % field.name, depth)
         self.emit("int res;", depth+1)
         if field.seq:
             self.emit("Py_ssize_t len;", depth+1)
             self.emit("Py_ssize_t i;", depth+1)
-        self.emit("tmp = PyObject_GetAttrString(obj, \"%s\");" % field.name, depth+1)
+        self.emit("tmp = _PyObject_GetAttrId(obj, &PyId_%s);" % field.name, depth+1)
         self.emit("if (tmp == NULL) goto failed;", depth+1)
         if field.seq:
             self.emit("if (!PyList_Check(tmp)) {", depth+1)
@@ -553,6 +561,8 @@
         self.emit("static PyTypeObject *%s_type;" % name, 0)
         self.emit("static PyObject* ast2obj_%s(void*);" % name, 0)
         if prod.fields:
+            for f in prod.fields:
+                self.emit_identifier(f.name)
             self.emit("static char *%s_fields[]={" % name,0)
             for f in prod.fields:
                 self.emit('"%s",' % f.name, 1)
@@ -561,6 +571,8 @@
     def visitSum(self, sum, name):
         self.emit("static PyTypeObject *%s_type;" % name, 0)
         if sum.attributes:
+            for a in sum.attributes:
+                self.emit_identifier(a.name)
             self.emit("static char *%s_attributes[] = {" % name, 0)
             for a in sum.attributes:
                 self.emit('"%s",' % a.name, 1)
@@ -580,6 +592,8 @@
     def visitConstructor(self, cons, name):
         self.emit("static PyTypeObject *%s_type;" % cons.name, 0)
         if cons.fields:
+            for t in cons.fields:
+                self.emit_identifier(t.name)
             self.emit("static char *%s_fields[]={" % cons.name, 0)
             for t in cons.fields:
                 self.emit('"%s",' % t.name, 1)
@@ -592,10 +606,11 @@
 static int
 ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
 {
+    _Py_identifier(_fields);
     Py_ssize_t i, numfields = 0;
     int res = -1;
     PyObject *key, *value, *fields;
-    fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields");
+    fields = _PyObject_GetAttrId((PyObject*)Py_TYPE(self), &PyId__fields);
     if (!fields)
         PyErr_Clear();
     if (fields) {
@@ -645,7 +660,8 @@
 ast_type_reduce(PyObject *self, PyObject *unused)
 {
     PyObject *res;
-    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    _Py_identifier(__dict__);
+    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
     if (dict == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_Clear();
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -463,6 +463,7 @@
 {
     PyObject *readline = NULL, *stream = NULL, *io = NULL;
     _Py_identifier(open);
+    _Py_identifier(readline);
     int fd;
 
     io = PyImport_ImportModuleNoBlock("io");
@@ -481,7 +482,7 @@
         goto cleanup;
 
     Py_XDECREF(tok->decoding_readline);
-    readline = PyObject_GetAttrString(stream, "readline");
+    readline = _PyObject_GetAttrId(stream, &PyId_readline);
     tok->decoding_readline = readline;
 
     /* The file has been reopened; parsing will restart from
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -7,6 +7,7 @@
 static PyTypeObject *mod_type;
 static PyObject* ast2obj_mod(void*);
 static PyTypeObject *Module_type;
+_Py_identifier(body);
 static char *Module_fields[]={
         "body",
 };
@@ -23,12 +24,18 @@
         "body",
 };
 static PyTypeObject *stmt_type;
+_Py_identifier(lineno);
+_Py_identifier(col_offset);
 static char *stmt_attributes[] = {
         "lineno",
         "col_offset",
 };
 static PyObject* ast2obj_stmt(void*);
 static PyTypeObject *FunctionDef_type;
+_Py_identifier(name);
+_Py_identifier(args);
+_Py_identifier(decorator_list);
+_Py_identifier(returns);
 static char *FunctionDef_fields[]={
         "name",
         "args",
@@ -37,6 +44,10 @@
         "returns",
 };
 static PyTypeObject *ClassDef_type;
+_Py_identifier(bases);
+_Py_identifier(keywords);
+_Py_identifier(starargs);
+_Py_identifier(kwargs);
 static char *ClassDef_fields[]={
         "name",
         "bases",
@@ -47,10 +58,12 @@
         "decorator_list",
 };
 static PyTypeObject *Return_type;
+_Py_identifier(value);
 static char *Return_fields[]={
         "value",
 };
 static PyTypeObject *Delete_type;
+_Py_identifier(targets);
 static char *Delete_fields[]={
         "targets",
 };
@@ -60,12 +73,16 @@
         "value",
 };
 static PyTypeObject *AugAssign_type;
+_Py_identifier(target);
+_Py_identifier(op);
 static char *AugAssign_fields[]={
         "target",
         "op",
         "value",
 };
 static PyTypeObject *For_type;
+_Py_identifier(iter);
+_Py_identifier(orelse);
 static char *For_fields[]={
         "target",
         "iter",
@@ -73,6 +90,7 @@
         "orelse",
 };
 static PyTypeObject *While_type;
+_Py_identifier(test);
 static char *While_fields[]={
         "test",
         "body",
@@ -85,16 +103,21 @@
         "orelse",
 };
 static PyTypeObject *With_type;
+_Py_identifier(items);
 static char *With_fields[]={
         "items",
         "body",
 };
 static PyTypeObject *Raise_type;
+_Py_identifier(exc);
+_Py_identifier(cause);
 static char *Raise_fields[]={
         "exc",
         "cause",
 };
 static PyTypeObject *Try_type;
+_Py_identifier(handlers);
+_Py_identifier(finalbody);
 static char *Try_fields[]={
         "body",
         "handlers",
@@ -102,15 +125,19 @@
         "finalbody",
 };
 static PyTypeObject *Assert_type;
+_Py_identifier(msg);
 static char *Assert_fields[]={
         "test",
         "msg",
 };
 static PyTypeObject *Import_type;
+_Py_identifier(names);
 static char *Import_fields[]={
         "names",
 };
 static PyTypeObject *ImportFrom_type;
+_Py_identifier(module);
+_Py_identifier(level);
 static char *ImportFrom_fields[]={
         "module",
         "names",
@@ -138,17 +165,21 @@
 };
 static PyObject* ast2obj_expr(void*);
 static PyTypeObject *BoolOp_type;
+_Py_identifier(values);
 static char *BoolOp_fields[]={
         "op",
         "values",
 };
 static PyTypeObject *BinOp_type;
+_Py_identifier(left);
+_Py_identifier(right);
 static char *BinOp_fields[]={
         "left",
         "op",
         "right",
 };
 static PyTypeObject *UnaryOp_type;
+_Py_identifier(operand);
 static char *UnaryOp_fields[]={
         "op",
         "operand",
@@ -165,15 +196,19 @@
         "orelse",
 };
 static PyTypeObject *Dict_type;
+_Py_identifier(keys);
 static char *Dict_fields[]={
         "keys",
         "values",
 };
 static PyTypeObject *Set_type;
+_Py_identifier(elts);
 static char *Set_fields[]={
         "elts",
 };
 static PyTypeObject *ListComp_type;
+_Py_identifier(elt);
+_Py_identifier(generators);
 static char *ListComp_fields[]={
         "elt",
         "generators",
@@ -184,6 +219,7 @@
         "generators",
 };
 static PyTypeObject *DictComp_type;
+_Py_identifier(key);
 static char *DictComp_fields[]={
         "key",
         "value",
@@ -199,12 +235,15 @@
         "value",
 };
 static PyTypeObject *Compare_type;
+_Py_identifier(ops);
+_Py_identifier(comparators);
 static char *Compare_fields[]={
         "left",
         "ops",
         "comparators",
 };
 static PyTypeObject *Call_type;
+_Py_identifier(func);
 static char *Call_fields[]={
         "func",
         "args",
@@ -213,10 +252,12 @@
         "kwargs",
 };
 static PyTypeObject *Num_type;
+_Py_identifier(n);
 static char *Num_fields[]={
         "n",
 };
 static PyTypeObject *Str_type;
+_Py_identifier(s);
 static char *Str_fields[]={
         "s",
 };
@@ -226,12 +267,15 @@
 };
 static PyTypeObject *Ellipsis_type;
 static PyTypeObject *Attribute_type;
+_Py_identifier(attr);
+_Py_identifier(ctx);
 static char *Attribute_fields[]={
         "value",
         "attr",
         "ctx",
 };
 static PyTypeObject *Subscript_type;
+_Py_identifier(slice);
 static char *Subscript_fields[]={
         "value",
         "slice",
@@ -243,6 +287,7 @@
         "ctx",
 };
 static PyTypeObject *Name_type;
+_Py_identifier(id);
 static char *Name_fields[]={
         "id",
         "ctx",
@@ -270,12 +315,16 @@
 static PyTypeObject *slice_type;
 static PyObject* ast2obj_slice(void*);
 static PyTypeObject *Slice_type;
+_Py_identifier(lower);
+_Py_identifier(upper);
+_Py_identifier(step);
 static char *Slice_fields[]={
         "lower",
         "upper",
         "step",
 };
 static PyTypeObject *ExtSlice_type;
+_Py_identifier(dims);
 static char *ExtSlice_fields[]={
         "dims",
 };
@@ -331,6 +380,7 @@
 static PyTypeObject *NotIn_type;
 static PyTypeObject *comprehension_type;
 static PyObject* ast2obj_comprehension(void*);
+_Py_identifier(ifs);
 static char *comprehension_fields[]={
         "target",
         "iter",
@@ -343,6 +393,7 @@
 };
 static PyObject* ast2obj_excepthandler(void*);
 static PyTypeObject *ExceptHandler_type;
+_Py_identifier(type);
 static char *ExceptHandler_fields[]={
         "type",
         "name",
@@ -350,6 +401,13 @@
 };
 static PyTypeObject *arguments_type;
 static PyObject* ast2obj_arguments(void*);
+_Py_identifier(vararg);
+_Py_identifier(varargannotation);
+_Py_identifier(kwonlyargs);
+_Py_identifier(kwarg);
+_Py_identifier(kwargannotation);
+_Py_identifier(defaults);
+_Py_identifier(kw_defaults);
 static char *arguments_fields[]={
         "args",
         "vararg",
@@ -362,6 +420,8 @@
 };
 static PyTypeObject *arg_type;
 static PyObject* ast2obj_arg(void*);
+_Py_identifier(arg);
+_Py_identifier(annotation);
 static char *arg_fields[]={
         "arg",
         "annotation",
@@ -374,12 +434,15 @@
 };
 static PyTypeObject *alias_type;
 static PyObject* ast2obj_alias(void*);
+_Py_identifier(asname);
 static char *alias_fields[]={
         "name",
         "asname",
 };
 static PyTypeObject *withitem_type;
 static PyObject* ast2obj_withitem(void*);
+_Py_identifier(context_expr);
+_Py_identifier(optional_vars);
 static char *withitem_fields[]={
         "context_expr",
         "optional_vars",
@@ -389,10 +452,11 @@
 static int
 ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
 {
+    _Py_identifier(_fields);
     Py_ssize_t i, numfields = 0;
     int res = -1;
     PyObject *key, *value, *fields;
-    fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields");
+    fields = _PyObject_GetAttrId((PyObject*)Py_TYPE(self), &PyId__fields);
     if (!fields)
         PyErr_Clear();
     if (fields) {
@@ -442,7 +506,8 @@
 ast_type_reduce(PyObject *self, PyObject *unused)
 {
     PyObject *res;
-    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    _Py_identifier(__dict__);
+    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
     if (dict == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_Clear();
@@ -3415,11 +3480,11 @@
         if (isinstance) {
                 asdl_seq* body;
 
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Module field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3451,11 +3516,11 @@
         if (isinstance) {
                 asdl_seq* body;
 
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Interactive field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3487,9 +3552,9 @@
         if (isinstance) {
                 expr_ty body;
 
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &body, arena);
                         if (res != 0) goto failed;
@@ -3510,11 +3575,11 @@
         if (isinstance) {
                 asdl_seq* body;
 
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Suite field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3559,9 +3624,9 @@
                 *out = NULL;
                 return 0;
         }
-        if (PyObject_HasAttrString(obj, "lineno")) {
+        if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "lineno");
+                tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &lineno, arena);
                 if (res != 0) goto failed;
@@ -3571,9 +3636,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from stmt");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "col_offset")) {
+        if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "col_offset");
+                tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &col_offset, arena);
                 if (res != 0) goto failed;
@@ -3594,9 +3659,9 @@
                 asdl_seq* decorator_list;
                 expr_ty returns;
 
-                if (PyObject_HasAttrString(obj, "name")) {
+                if (_PyObject_HasAttrId(obj, &PyId_name)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "name");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_name);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &name, arena);
                         if (res != 0) goto failed;
@@ -3606,9 +3671,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from FunctionDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "args")) {
+                if (_PyObject_HasAttrId(obj, &PyId_args)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "args");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_args);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_arguments(tmp, &args, arena);
                         if (res != 0) goto failed;
@@ -3618,11 +3683,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from FunctionDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "FunctionDef field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3643,11 +3708,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "decorator_list")) {
+                if (_PyObject_HasAttrId(obj, &PyId_decorator_list)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "decorator_list");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_decorator_list);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "FunctionDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3668,9 +3733,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "returns")) {
+                if (_PyObject_HasAttrId(obj, &PyId_returns)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "returns");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_returns);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &returns, arena);
                         if (res != 0) goto failed;
@@ -3697,9 +3762,9 @@
                 asdl_seq* body;
                 asdl_seq* decorator_list;
 
-                if (PyObject_HasAttrString(obj, "name")) {
+                if (_PyObject_HasAttrId(obj, &PyId_name)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "name");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_name);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &name, arena);
                         if (res != 0) goto failed;
@@ -3709,11 +3774,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "bases")) {
+                if (_PyObject_HasAttrId(obj, &PyId_bases)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "bases");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_bases);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3734,11 +3799,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "keywords")) {
+                if (_PyObject_HasAttrId(obj, &PyId_keywords)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "keywords");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_keywords);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3759,9 +3824,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "starargs")) {
+                if (_PyObject_HasAttrId(obj, &PyId_starargs)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "starargs");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_starargs);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &starargs, arena);
                         if (res != 0) goto failed;
@@ -3770,9 +3835,9 @@
                 } else {
                         starargs = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "kwargs")) {
+                if (_PyObject_HasAttrId(obj, &PyId_kwargs)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "kwargs");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_kwargs);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &kwargs, arena);
                         if (res != 0) goto failed;
@@ -3781,11 +3846,11 @@
                 } else {
                         kwargs = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ClassDef field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3806,11 +3871,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "decorator_list")) {
+                if (_PyObject_HasAttrId(obj, &PyId_decorator_list)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "decorator_list");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_decorator_list);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ClassDef field \"decorator_list\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3843,9 +3908,9 @@
         if (isinstance) {
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -3865,11 +3930,11 @@
         if (isinstance) {
                 asdl_seq* targets;
 
-                if (PyObject_HasAttrString(obj, "targets")) {
+                if (_PyObject_HasAttrId(obj, &PyId_targets)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "targets");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_targets);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Delete field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3902,11 +3967,11 @@
                 asdl_seq* targets;
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "targets")) {
+                if (_PyObject_HasAttrId(obj, &PyId_targets)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "targets");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_targets);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Assign field \"targets\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -3927,9 +3992,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -3952,9 +4017,9 @@
                 operator_ty op;
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "target")) {
+                if (_PyObject_HasAttrId(obj, &PyId_target)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "target");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_target);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &target, arena);
                         if (res != 0) goto failed;
@@ -3964,9 +4029,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AugAssign");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "op")) {
+                if (_PyObject_HasAttrId(obj, &PyId_op)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "op");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_op);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_operator(tmp, &op, arena);
                         if (res != 0) goto failed;
@@ -3976,9 +4041,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from AugAssign");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -4002,9 +4067,9 @@
                 asdl_seq* body;
                 asdl_seq* orelse;
 
-                if (PyObject_HasAttrString(obj, "target")) {
+                if (_PyObject_HasAttrId(obj, &PyId_target)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "target");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_target);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &target, arena);
                         if (res != 0) goto failed;
@@ -4014,9 +4079,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from For");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "iter")) {
+                if (_PyObject_HasAttrId(obj, &PyId_iter)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "iter");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_iter);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &iter, arena);
                         if (res != 0) goto failed;
@@ -4026,11 +4091,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from For");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "For field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4051,11 +4116,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "orelse")) {
+                if (_PyObject_HasAttrId(obj, &PyId_orelse)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "orelse");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_orelse);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "For field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4090,9 +4155,9 @@
                 asdl_seq* body;
                 asdl_seq* orelse;
 
-                if (PyObject_HasAttrString(obj, "test")) {
+                if (_PyObject_HasAttrId(obj, &PyId_test)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "test");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_test);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &test, arena);
                         if (res != 0) goto failed;
@@ -4102,11 +4167,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from While");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "While field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4127,11 +4192,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "orelse")) {
+                if (_PyObject_HasAttrId(obj, &PyId_orelse)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "orelse");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_orelse);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "While field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4165,9 +4230,9 @@
                 asdl_seq* body;
                 asdl_seq* orelse;
 
-                if (PyObject_HasAttrString(obj, "test")) {
+                if (_PyObject_HasAttrId(obj, &PyId_test)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "test");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_test);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &test, arena);
                         if (res != 0) goto failed;
@@ -4177,11 +4242,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from If");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "If field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4202,11 +4267,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "orelse")) {
+                if (_PyObject_HasAttrId(obj, &PyId_orelse)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "orelse");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_orelse);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "If field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4239,11 +4304,11 @@
                 asdl_seq* items;
                 asdl_seq* body;
 
-                if (PyObject_HasAttrString(obj, "items")) {
+                if (_PyObject_HasAttrId(obj, &PyId_items)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "items");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_items);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4264,11 +4329,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "With field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4301,9 +4366,9 @@
                 expr_ty exc;
                 expr_ty cause;
 
-                if (PyObject_HasAttrString(obj, "exc")) {
+                if (_PyObject_HasAttrId(obj, &PyId_exc)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "exc");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_exc);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &exc, arena);
                         if (res != 0) goto failed;
@@ -4312,9 +4377,9 @@
                 } else {
                         exc = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "cause")) {
+                if (_PyObject_HasAttrId(obj, &PyId_cause)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "cause");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_cause);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &cause, arena);
                         if (res != 0) goto failed;
@@ -4337,11 +4402,11 @@
                 asdl_seq* orelse;
                 asdl_seq* finalbody;
 
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4362,11 +4427,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "handlers")) {
+                if (_PyObject_HasAttrId(obj, &PyId_handlers)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "handlers");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_handlers);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4387,11 +4452,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "orelse")) {
+                if (_PyObject_HasAttrId(obj, &PyId_orelse)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "orelse");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_orelse);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4412,11 +4477,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "finalbody")) {
+                if (_PyObject_HasAttrId(obj, &PyId_finalbody)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "finalbody");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_finalbody);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4450,9 +4515,9 @@
                 expr_ty test;
                 expr_ty msg;
 
-                if (PyObject_HasAttrString(obj, "test")) {
+                if (_PyObject_HasAttrId(obj, &PyId_test)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "test");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_test);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &test, arena);
                         if (res != 0) goto failed;
@@ -4462,9 +4527,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from Assert");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "msg")) {
+                if (_PyObject_HasAttrId(obj, &PyId_msg)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "msg");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_msg);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &msg, arena);
                         if (res != 0) goto failed;
@@ -4484,11 +4549,11 @@
         if (isinstance) {
                 asdl_seq* names;
 
-                if (PyObject_HasAttrString(obj, "names")) {
+                if (_PyObject_HasAttrId(obj, &PyId_names)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "names");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_names);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Import field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4522,9 +4587,9 @@
                 asdl_seq* names;
                 int level;
 
-                if (PyObject_HasAttrString(obj, "module")) {
+                if (_PyObject_HasAttrId(obj, &PyId_module)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "module");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_module);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &module, arena);
                         if (res != 0) goto failed;
@@ -4533,11 +4598,11 @@
                 } else {
                         module = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "names")) {
+                if (_PyObject_HasAttrId(obj, &PyId_names)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "names");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_names);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ImportFrom field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4558,9 +4623,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "level")) {
+                if (_PyObject_HasAttrId(obj, &PyId_level)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "level");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_level);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_int(tmp, &level, arena);
                         if (res != 0) goto failed;
@@ -4581,11 +4646,11 @@
         if (isinstance) {
                 asdl_seq* names;
 
-                if (PyObject_HasAttrString(obj, "names")) {
+                if (_PyObject_HasAttrId(obj, &PyId_names)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "names");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_names);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Global field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4617,11 +4682,11 @@
         if (isinstance) {
                 asdl_seq* names;
 
-                if (PyObject_HasAttrString(obj, "names")) {
+                if (_PyObject_HasAttrId(obj, &PyId_names)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "names");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_names);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Nonlocal field \"names\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4653,9 +4718,9 @@
         if (isinstance) {
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -4719,9 +4784,9 @@
                 *out = NULL;
                 return 0;
         }
-        if (PyObject_HasAttrString(obj, "lineno")) {
+        if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "lineno");
+                tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &lineno, arena);
                 if (res != 0) goto failed;
@@ -4731,9 +4796,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from expr");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "col_offset")) {
+        if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "col_offset");
+                tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &col_offset, arena);
                 if (res != 0) goto failed;
@@ -4751,9 +4816,9 @@
                 boolop_ty op;
                 asdl_seq* values;
 
-                if (PyObject_HasAttrString(obj, "op")) {
+                if (_PyObject_HasAttrId(obj, &PyId_op)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "op");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_op);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_boolop(tmp, &op, arena);
                         if (res != 0) goto failed;
@@ -4763,11 +4828,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BoolOp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "values")) {
+                if (_PyObject_HasAttrId(obj, &PyId_values)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "values");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_values);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "BoolOp field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4801,9 +4866,9 @@
                 operator_ty op;
                 expr_ty right;
 
-                if (PyObject_HasAttrString(obj, "left")) {
+                if (_PyObject_HasAttrId(obj, &PyId_left)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "left");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_left);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &left, arena);
                         if (res != 0) goto failed;
@@ -4813,9 +4878,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from BinOp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "op")) {
+                if (_PyObject_HasAttrId(obj, &PyId_op)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "op");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_op);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_operator(tmp, &op, arena);
                         if (res != 0) goto failed;
@@ -4825,9 +4890,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from BinOp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "right")) {
+                if (_PyObject_HasAttrId(obj, &PyId_right)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "right");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_right);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &right, arena);
                         if (res != 0) goto failed;
@@ -4849,9 +4914,9 @@
                 unaryop_ty op;
                 expr_ty operand;
 
-                if (PyObject_HasAttrString(obj, "op")) {
+                if (_PyObject_HasAttrId(obj, &PyId_op)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "op");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_op);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_unaryop(tmp, &op, arena);
                         if (res != 0) goto failed;
@@ -4861,9 +4926,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"op\" missing from UnaryOp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "operand")) {
+                if (_PyObject_HasAttrId(obj, &PyId_operand)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "operand");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_operand);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &operand, arena);
                         if (res != 0) goto failed;
@@ -4885,9 +4950,9 @@
                 arguments_ty args;
                 expr_ty body;
 
-                if (PyObject_HasAttrString(obj, "args")) {
+                if (_PyObject_HasAttrId(obj, &PyId_args)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "args");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_args);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_arguments(tmp, &args, arena);
                         if (res != 0) goto failed;
@@ -4897,9 +4962,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Lambda");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &body, arena);
                         if (res != 0) goto failed;
@@ -4922,9 +4987,9 @@
                 expr_ty body;
                 expr_ty orelse;
 
-                if (PyObject_HasAttrString(obj, "test")) {
+                if (_PyObject_HasAttrId(obj, &PyId_test)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "test");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_test);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &test, arena);
                         if (res != 0) goto failed;
@@ -4934,9 +4999,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"test\" missing from IfExp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &body, arena);
                         if (res != 0) goto failed;
@@ -4946,9 +5011,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from IfExp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "orelse")) {
+                if (_PyObject_HasAttrId(obj, &PyId_orelse)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "orelse");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_orelse);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &orelse, arena);
                         if (res != 0) goto failed;
@@ -4970,11 +5035,11 @@
                 asdl_seq* keys;
                 asdl_seq* values;
 
-                if (PyObject_HasAttrString(obj, "keys")) {
+                if (_PyObject_HasAttrId(obj, &PyId_keys)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "keys");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_keys);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Dict field \"keys\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -4995,11 +5060,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "values")) {
+                if (_PyObject_HasAttrId(obj, &PyId_values)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "values");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_values);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Dict field \"values\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5031,11 +5096,11 @@
         if (isinstance) {
                 asdl_seq* elts;
 
-                if (PyObject_HasAttrString(obj, "elts")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elts)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "elts");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elts);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Set field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5068,9 +5133,9 @@
                 expr_ty elt;
                 asdl_seq* generators;
 
-                if (PyObject_HasAttrString(obj, "elt")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elt)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "elt");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elt);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &elt, arena);
                         if (res != 0) goto failed;
@@ -5080,11 +5145,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from ListComp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "generators")) {
+                if (_PyObject_HasAttrId(obj, &PyId_generators)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "generators");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_generators);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ListComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5117,9 +5182,9 @@
                 expr_ty elt;
                 asdl_seq* generators;
 
-                if (PyObject_HasAttrString(obj, "elt")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elt)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "elt");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elt);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &elt, arena);
                         if (res != 0) goto failed;
@@ -5129,11 +5194,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from SetComp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "generators")) {
+                if (_PyObject_HasAttrId(obj, &PyId_generators)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "generators");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_generators);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "SetComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5167,9 +5232,9 @@
                 expr_ty value;
                 asdl_seq* generators;
 
-                if (PyObject_HasAttrString(obj, "key")) {
+                if (_PyObject_HasAttrId(obj, &PyId_key)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "key");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_key);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &key, arena);
                         if (res != 0) goto failed;
@@ -5179,9 +5244,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"key\" missing from DictComp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -5191,11 +5256,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from DictComp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "generators")) {
+                if (_PyObject_HasAttrId(obj, &PyId_generators)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "generators");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_generators);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "DictComp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5229,9 +5294,9 @@
                 expr_ty elt;
                 asdl_seq* generators;
 
-                if (PyObject_HasAttrString(obj, "elt")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elt)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "elt");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elt);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &elt, arena);
                         if (res != 0) goto failed;
@@ -5241,11 +5306,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"elt\" missing from GeneratorExp");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "generators")) {
+                if (_PyObject_HasAttrId(obj, &PyId_generators)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "generators");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_generators);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "GeneratorExp field \"generators\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5277,9 +5342,9 @@
         if (isinstance) {
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -5301,9 +5366,9 @@
                 asdl_int_seq* ops;
                 asdl_seq* comparators;
 
-                if (PyObject_HasAttrString(obj, "left")) {
+                if (_PyObject_HasAttrId(obj, &PyId_left)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "left");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_left);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &left, arena);
                         if (res != 0) goto failed;
@@ -5313,11 +5378,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"left\" missing from Compare");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ops")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ops)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "ops");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ops);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Compare field \"ops\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5338,11 +5403,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "comparators")) {
+                if (_PyObject_HasAttrId(obj, &PyId_comparators)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "comparators");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_comparators);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Compare field \"comparators\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5379,9 +5444,9 @@
                 expr_ty starargs;
                 expr_ty kwargs;
 
-                if (PyObject_HasAttrString(obj, "func")) {
+                if (_PyObject_HasAttrId(obj, &PyId_func)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "func");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_func);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &func, arena);
                         if (res != 0) goto failed;
@@ -5391,11 +5456,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"func\" missing from Call");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "args")) {
+                if (_PyObject_HasAttrId(obj, &PyId_args)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "args");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_args);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Call field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5416,11 +5481,11 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "keywords")) {
+                if (_PyObject_HasAttrId(obj, &PyId_keywords)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "keywords");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_keywords);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Call field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5441,9 +5506,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "starargs")) {
+                if (_PyObject_HasAttrId(obj, &PyId_starargs)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "starargs");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_starargs);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &starargs, arena);
                         if (res != 0) goto failed;
@@ -5452,9 +5517,9 @@
                 } else {
                         starargs = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "kwargs")) {
+                if (_PyObject_HasAttrId(obj, &PyId_kwargs)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "kwargs");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_kwargs);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &kwargs, arena);
                         if (res != 0) goto failed;
@@ -5475,9 +5540,9 @@
         if (isinstance) {
                 object n;
 
-                if (PyObject_HasAttrString(obj, "n")) {
+                if (_PyObject_HasAttrId(obj, &PyId_n)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "n");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_n);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_object(tmp, &n, arena);
                         if (res != 0) goto failed;
@@ -5498,9 +5563,9 @@
         if (isinstance) {
                 string s;
 
-                if (PyObject_HasAttrString(obj, "s")) {
+                if (_PyObject_HasAttrId(obj, &PyId_s)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "s");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_s);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_string(tmp, &s, arena);
                         if (res != 0) goto failed;
@@ -5521,9 +5586,9 @@
         if (isinstance) {
                 bytes s;
 
-                if (PyObject_HasAttrString(obj, "s")) {
+                if (_PyObject_HasAttrId(obj, &PyId_s)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "s");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_s);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_bytes(tmp, &s, arena);
                         if (res != 0) goto failed;
@@ -5556,9 +5621,9 @@
                 identifier attr;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -5568,9 +5633,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Attribute");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "attr")) {
+                if (_PyObject_HasAttrId(obj, &PyId_attr)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "attr");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_attr);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &attr, arena);
                         if (res != 0) goto failed;
@@ -5580,9 +5645,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"attr\" missing from Attribute");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5605,9 +5670,9 @@
                 slice_ty slice;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -5617,9 +5682,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Subscript");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "slice")) {
+                if (_PyObject_HasAttrId(obj, &PyId_slice)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "slice");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_slice);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_slice(tmp, &slice, arena);
                         if (res != 0) goto failed;
@@ -5629,9 +5694,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"slice\" missing from Subscript");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5653,9 +5718,9 @@
                 expr_ty value;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -5665,9 +5730,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Starred");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5689,9 +5754,9 @@
                 identifier id;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "id")) {
+                if (_PyObject_HasAttrId(obj, &PyId_id)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "id");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_id);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &id, arena);
                         if (res != 0) goto failed;
@@ -5701,9 +5766,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"id\" missing from Name");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5725,11 +5790,11 @@
                 asdl_seq* elts;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "elts")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elts)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "elts");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elts);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "List field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5750,9 +5815,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5774,11 +5839,11 @@
                 asdl_seq* elts;
                 expr_context_ty ctx;
 
-                if (PyObject_HasAttrString(obj, "elts")) {
+                if (_PyObject_HasAttrId(obj, &PyId_elts)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "elts");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_elts);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "Tuple field \"elts\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5799,9 +5864,9 @@
                         PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple");
                         return 1;
                 }
-                if (PyObject_HasAttrString(obj, "ctx")) {
+                if (_PyObject_HasAttrId(obj, &PyId_ctx)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "ctx");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_ctx);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr_context(tmp, &ctx, arena);
                         if (res != 0) goto failed;
@@ -5900,9 +5965,9 @@
                 expr_ty upper;
                 expr_ty step;
 
-                if (PyObject_HasAttrString(obj, "lower")) {
+                if (_PyObject_HasAttrId(obj, &PyId_lower)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "lower");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_lower);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &lower, arena);
                         if (res != 0) goto failed;
@@ -5911,9 +5976,9 @@
                 } else {
                         lower = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "upper")) {
+                if (_PyObject_HasAttrId(obj, &PyId_upper)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "upper");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_upper);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &upper, arena);
                         if (res != 0) goto failed;
@@ -5922,9 +5987,9 @@
                 } else {
                         upper = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "step")) {
+                if (_PyObject_HasAttrId(obj, &PyId_step)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "step");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_step);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &step, arena);
                         if (res != 0) goto failed;
@@ -5944,11 +6009,11 @@
         if (isinstance) {
                 asdl_seq* dims;
 
-                if (PyObject_HasAttrString(obj, "dims")) {
+                if (_PyObject_HasAttrId(obj, &PyId_dims)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "dims");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_dims);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ExtSlice field \"dims\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -5980,9 +6045,9 @@
         if (isinstance) {
                 expr_ty value;
 
-                if (PyObject_HasAttrString(obj, "value")) {
+                if (_PyObject_HasAttrId(obj, &PyId_value)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "value");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_value);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &value, arena);
                         if (res != 0) goto failed;
@@ -6275,9 +6340,9 @@
         expr_ty iter;
         asdl_seq* ifs;
 
-        if (PyObject_HasAttrString(obj, "target")) {
+        if (_PyObject_HasAttrId(obj, &PyId_target)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "target");
+                tmp = _PyObject_GetAttrId(obj, &PyId_target);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &target, arena);
                 if (res != 0) goto failed;
@@ -6287,9 +6352,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from comprehension");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "iter")) {
+        if (_PyObject_HasAttrId(obj, &PyId_iter)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "iter");
+                tmp = _PyObject_GetAttrId(obj, &PyId_iter);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &iter, arena);
                 if (res != 0) goto failed;
@@ -6299,11 +6364,11 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from comprehension");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "ifs")) {
+        if (_PyObject_HasAttrId(obj, &PyId_ifs)) {
                 int res;
                 Py_ssize_t len;
                 Py_ssize_t i;
-                tmp = PyObject_GetAttrString(obj, "ifs");
+                tmp = _PyObject_GetAttrId(obj, &PyId_ifs);
                 if (tmp == NULL) goto failed;
                 if (!PyList_Check(tmp)) {
                         PyErr_Format(PyExc_TypeError, "comprehension field \"ifs\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6344,9 +6409,9 @@
                 *out = NULL;
                 return 0;
         }
-        if (PyObject_HasAttrString(obj, "lineno")) {
+        if (_PyObject_HasAttrId(obj, &PyId_lineno)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "lineno");
+                tmp = _PyObject_GetAttrId(obj, &PyId_lineno);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &lineno, arena);
                 if (res != 0) goto failed;
@@ -6356,9 +6421,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from excepthandler");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "col_offset")) {
+        if (_PyObject_HasAttrId(obj, &PyId_col_offset)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "col_offset");
+                tmp = _PyObject_GetAttrId(obj, &PyId_col_offset);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_int(tmp, &col_offset, arena);
                 if (res != 0) goto failed;
@@ -6377,9 +6442,9 @@
                 identifier name;
                 asdl_seq* body;
 
-                if (PyObject_HasAttrString(obj, "type")) {
+                if (_PyObject_HasAttrId(obj, &PyId_type)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "type");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_type);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_expr(tmp, &type, arena);
                         if (res != 0) goto failed;
@@ -6388,9 +6453,9 @@
                 } else {
                         type = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "name")) {
+                if (_PyObject_HasAttrId(obj, &PyId_name)) {
                         int res;
-                        tmp = PyObject_GetAttrString(obj, "name");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_name);
                         if (tmp == NULL) goto failed;
                         res = obj2ast_identifier(tmp, &name, arena);
                         if (res != 0) goto failed;
@@ -6399,11 +6464,11 @@
                 } else {
                         name = NULL;
                 }
-                if (PyObject_HasAttrString(obj, "body")) {
+                if (_PyObject_HasAttrId(obj, &PyId_body)) {
                         int res;
                         Py_ssize_t len;
                         Py_ssize_t i;
-                        tmp = PyObject_GetAttrString(obj, "body");
+                        tmp = _PyObject_GetAttrId(obj, &PyId_body);
                         if (tmp == NULL) goto failed;
                         if (!PyList_Check(tmp)) {
                                 PyErr_Format(PyExc_TypeError, "ExceptHandler field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6449,11 +6514,11 @@
         asdl_seq* defaults;
         asdl_seq* kw_defaults;
 
-        if (PyObject_HasAttrString(obj, "args")) {
+        if (_PyObject_HasAttrId(obj, &PyId_args)) {
                 int res;
                 Py_ssize_t len;
                 Py_ssize_t i;
-                tmp = PyObject_GetAttrString(obj, "args");
+                tmp = _PyObject_GetAttrId(obj, &PyId_args);
                 if (tmp == NULL) goto failed;
                 if (!PyList_Check(tmp)) {
                         PyErr_Format(PyExc_TypeError, "arguments field \"args\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6474,9 +6539,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "vararg")) {
+        if (_PyObject_HasAttrId(obj, &PyId_vararg)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "vararg");
+                tmp = _PyObject_GetAttrId(obj, &PyId_vararg);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &vararg, arena);
                 if (res != 0) goto failed;
@@ -6485,9 +6550,9 @@
         } else {
                 vararg = NULL;
         }
-        if (PyObject_HasAttrString(obj, "varargannotation")) {
+        if (_PyObject_HasAttrId(obj, &PyId_varargannotation)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "varargannotation");
+                tmp = _PyObject_GetAttrId(obj, &PyId_varargannotation);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &varargannotation, arena);
                 if (res != 0) goto failed;
@@ -6496,11 +6561,11 @@
         } else {
                 varargannotation = NULL;
         }
-        if (PyObject_HasAttrString(obj, "kwonlyargs")) {
+        if (_PyObject_HasAttrId(obj, &PyId_kwonlyargs)) {
                 int res;
                 Py_ssize_t len;
                 Py_ssize_t i;
-                tmp = PyObject_GetAttrString(obj, "kwonlyargs");
+                tmp = _PyObject_GetAttrId(obj, &PyId_kwonlyargs);
                 if (tmp == NULL) goto failed;
                 if (!PyList_Check(tmp)) {
                         PyErr_Format(PyExc_TypeError, "arguments field \"kwonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6521,9 +6586,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "kwarg")) {
+        if (_PyObject_HasAttrId(obj, &PyId_kwarg)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "kwarg");
+                tmp = _PyObject_GetAttrId(obj, &PyId_kwarg);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &kwarg, arena);
                 if (res != 0) goto failed;
@@ -6532,9 +6597,9 @@
         } else {
                 kwarg = NULL;
         }
-        if (PyObject_HasAttrString(obj, "kwargannotation")) {
+        if (_PyObject_HasAttrId(obj, &PyId_kwargannotation)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "kwargannotation");
+                tmp = _PyObject_GetAttrId(obj, &PyId_kwargannotation);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &kwargannotation, arena);
                 if (res != 0) goto failed;
@@ -6543,11 +6608,11 @@
         } else {
                 kwargannotation = NULL;
         }
-        if (PyObject_HasAttrString(obj, "defaults")) {
+        if (_PyObject_HasAttrId(obj, &PyId_defaults)) {
                 int res;
                 Py_ssize_t len;
                 Py_ssize_t i;
-                tmp = PyObject_GetAttrString(obj, "defaults");
+                tmp = _PyObject_GetAttrId(obj, &PyId_defaults);
                 if (tmp == NULL) goto failed;
                 if (!PyList_Check(tmp)) {
                         PyErr_Format(PyExc_TypeError, "arguments field \"defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6568,11 +6633,11 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "kw_defaults")) {
+        if (_PyObject_HasAttrId(obj, &PyId_kw_defaults)) {
                 int res;
                 Py_ssize_t len;
                 Py_ssize_t i;
-                tmp = PyObject_GetAttrString(obj, "kw_defaults");
+                tmp = _PyObject_GetAttrId(obj, &PyId_kw_defaults);
                 if (tmp == NULL) goto failed;
                 if (!PyList_Check(tmp)) {
                         PyErr_Format(PyExc_TypeError, "arguments field \"kw_defaults\" must be a list, not a %.200s", tmp->ob_type->tp_name);
@@ -6608,9 +6673,9 @@
         identifier arg;
         expr_ty annotation;
 
-        if (PyObject_HasAttrString(obj, "arg")) {
+        if (_PyObject_HasAttrId(obj, &PyId_arg)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "arg");
+                tmp = _PyObject_GetAttrId(obj, &PyId_arg);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &arg, arena);
                 if (res != 0) goto failed;
@@ -6620,9 +6685,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from arg");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "annotation")) {
+        if (_PyObject_HasAttrId(obj, &PyId_annotation)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "annotation");
+                tmp = _PyObject_GetAttrId(obj, &PyId_annotation);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &annotation, arena);
                 if (res != 0) goto failed;
@@ -6645,9 +6710,9 @@
         identifier arg;
         expr_ty value;
 
-        if (PyObject_HasAttrString(obj, "arg")) {
+        if (_PyObject_HasAttrId(obj, &PyId_arg)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "arg");
+                tmp = _PyObject_GetAttrId(obj, &PyId_arg);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &arg, arena);
                 if (res != 0) goto failed;
@@ -6657,9 +6722,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from keyword");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "value")) {
+        if (_PyObject_HasAttrId(obj, &PyId_value)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "value");
+                tmp = _PyObject_GetAttrId(obj, &PyId_value);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &value, arena);
                 if (res != 0) goto failed;
@@ -6683,9 +6748,9 @@
         identifier name;
         identifier asname;
 
-        if (PyObject_HasAttrString(obj, "name")) {
+        if (_PyObject_HasAttrId(obj, &PyId_name)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "name");
+                tmp = _PyObject_GetAttrId(obj, &PyId_name);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &name, arena);
                 if (res != 0) goto failed;
@@ -6695,9 +6760,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from alias");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "asname")) {
+        if (_PyObject_HasAttrId(obj, &PyId_asname)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "asname");
+                tmp = _PyObject_GetAttrId(obj, &PyId_asname);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_identifier(tmp, &asname, arena);
                 if (res != 0) goto failed;
@@ -6720,9 +6785,9 @@
         expr_ty context_expr;
         expr_ty optional_vars;
 
-        if (PyObject_HasAttrString(obj, "context_expr")) {
+        if (_PyObject_HasAttrId(obj, &PyId_context_expr)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "context_expr");
+                tmp = _PyObject_GetAttrId(obj, &PyId_context_expr);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &context_expr, arena);
                 if (res != 0) goto failed;
@@ -6732,9 +6797,9 @@
                 PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem");
                 return 1;
         }
-        if (PyObject_HasAttrString(obj, "optional_vars")) {
+        if (_PyObject_HasAttrId(obj, &PyId_optional_vars)) {
                 int res;
-                tmp = PyObject_GetAttrString(obj, "optional_vars");
+                tmp = _PyObject_GetAttrId(obj, &PyId_optional_vars);
                 if (tmp == NULL) goto failed;
                 res = obj2ast_expr(tmp, &optional_vars, arena);
                 if (res != 0) goto failed;
diff --git a/Python/_warnings.c b/Python/_warnings.c
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -247,10 +247,11 @@
     PyObject *f_stderr;
     PyObject *name;
     char lineno_str[128];
+    _Py_identifier(__name__);
 
     PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno);
 
-    name = PyObject_GetAttrString(category, "__name__");
+    name = _PyObject_GetAttrId(category, &PyId___name__);
     if (name == NULL)  /* XXX Can an object lack a '__name__' attribute? */
         return;
 
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -41,6 +41,7 @@
     PyObject *func, *name, *bases, *mkw, *meta, *prep, *ns, *cell;
     PyObject *cls = NULL;
     Py_ssize_t nargs;
+    _Py_identifier(__prepare__);
 
     assert(args != NULL);
     if (!PyTuple_Check(args)) {
@@ -95,7 +96,7 @@
         }
         Py_INCREF(meta);
     }
-    prep = PyObject_GetAttrString(meta, "__prepare__");
+    prep = _PyObject_GetAttrId(meta, &PyId___prepare__);
     if (prep == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
             PyErr_Clear();
@@ -1613,8 +1614,9 @@
         char *stdin_encoding_str;
         PyObject *result;
         size_t len;
+        _Py_identifier(encoding);
 
-        stdin_encoding = PyObject_GetAttrString(fin, "encoding");
+        stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding);
         if (!stdin_encoding)
             /* stdin is a text stream, so it must have an
                encoding. */
@@ -1633,7 +1635,7 @@
             PyObject *stringpo;
             PyObject *stdout_encoding;
             char *stdout_encoding_str;
-            stdout_encoding = PyObject_GetAttrString(fout, "encoding");
+            stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding);
             if (stdout_encoding == NULL) {
                 Py_DECREF(stdin_encoding);
                 return NULL;
@@ -1788,6 +1790,7 @@
     PyObject *callable;
     static char *kwlist[] = {"iterable", "key", "reverse", 0};
     int reverse;
+    _Py_identifier(sort);
 
     /* args 1-3 should match listsort in Objects/listobject.c */
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:sorted",
@@ -1798,7 +1801,7 @@
     if (newlist == NULL)
         return NULL;
 
-    callable = PyObject_GetAttrString(newlist, "sort");
+    callable = _PyObject_GetAttrId(newlist, &PyId_sort);
     if (callable == NULL) {
         Py_DECREF(newlist);
         return NULL;
@@ -1844,7 +1847,8 @@
             Py_INCREF(d);
     }
     else {
-        d = PyObject_GetAttrString(v, "__dict__");
+        _Py_identifier(__dict__);
+        d = _PyObject_GetAttrId(v, &PyId___dict__);
         if (d == NULL) {
             PyErr_SetString(PyExc_TypeError,
                 "vars() argument must have __dict__ attribute");
diff --git a/Python/codecs.c b/Python/codecs.c
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -465,9 +465,11 @@
 
 static void wrong_exception_type(PyObject *exc)
 {
-    PyObject *type = PyObject_GetAttrString(exc, "__class__");
+    _Py_identifier(__class__);
+    _Py_identifier(__name__);
+    PyObject *type = _PyObject_GetAttrId(exc, &PyId___class__);
     if (type != NULL) {
-        PyObject *name = PyObject_GetAttrString(type, "__name__");
+        PyObject *name = _PyObject_GetAttrId(type, &PyId___name__);
         Py_DECREF(type);
         if (name != NULL) {
             PyErr_Format(PyExc_TypeError,
diff --git a/Python/errors.c b/Python/errors.c
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -707,6 +707,7 @@
 void
 PyErr_WriteUnraisable(PyObject *obj)
 {
+    _Py_identifier(__module__);
     PyObject *f, *t, *v, *tb;
     PyErr_Fetch(&t, &v, &tb);
     f = PySys_GetObject("stderr");
@@ -723,7 +724,7 @@
                     className = dot+1;
             }
 
-            moduleName = PyObject_GetAttrString(t, "__module__");
+            moduleName = _PyObject_GetAttrId(t, &PyId___module__);
             if (moduleName == NULL)
                 PyFile_WriteString("<unknown>", f);
             else {
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -154,7 +154,7 @@
 };
 
 static PyObject *initstr = NULL;
-
+_Py_identifier(__path__);
 
 /* Initialize things */
 
@@ -248,8 +248,9 @@
             PySys_WriteStderr("# can't import zipimport\n");
     }
     else {
-        PyObject *zipimporter = PyObject_GetAttrString(zimpimport,
-                                                       "zipimporter");
+        _Py_identifier(zipimporter);
+        PyObject *zipimporter = _PyObject_GetAttrId(zimpimport,
+                                                    &PyId_zipimporter);
         Py_DECREF(zimpimport);
         if (zipimporter == NULL) {
             PyErr_Clear(); /* No zipimporter object -- okay */
@@ -3203,7 +3204,7 @@
     PyObject *fullname;
     Py_ssize_t fromlist_len;
 
-    if (!PyObject_HasAttrString(mod, "__path__"))
+    if (!_PyObject_HasAttrId(mod, &PyId___path__))
         return 1;
 
     fromlist_len = PySequence_Size(fromlist);
@@ -3221,11 +3222,12 @@
         }
         if (PyUnicode_READ_CHAR(item, 0) == '*') {
             PyObject *all;
+            _Py_identifier(__all__);
             Py_DECREF(item);
             /* See if the package defines __all__ */
             if (recursive)
                 continue; /* Avoid endless recursion */
-            all = PyObject_GetAttrString(mod, "__all__");
+            all = _PyObject_GetAttrId(mod, &PyId___all__);
             if (all == NULL)
                 PyErr_Clear();
             else {
@@ -3313,7 +3315,7 @@
     if (mod == Py_None)
         path_list = NULL;
     else {
-        path_list = PyObject_GetAttrString(mod, "__path__");
+        path_list = _PyObject_GetAttrId(mod, &PyId___path__);
         if (path_list == NULL) {
             PyErr_Clear();
             Py_INCREF(Py_None);
@@ -3424,7 +3426,7 @@
             goto error;
         }
         Py_DECREF(parentname);
-        path_list = PyObject_GetAttrString(parent, "__path__");
+        path_list = _PyObject_GetAttrId(parent, &PyId___path__);
         if (path_list == NULL)
             PyErr_Clear();
         subname++;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -141,12 +141,13 @@
 {
     char *name_utf8, *name_str;
     PyObject *codec, *name = NULL;
+    _Py_identifier(name);
 
     codec = _PyCodec_Lookup(encoding);
     if (!codec)
         goto error;
 
-    name = PyObject_GetAttrString(codec, "name");
+    name = _PyObject_GetAttrId(codec, &PyId_name);
     Py_CLEAR(codec);
     if (!name)
         goto error;
@@ -830,7 +831,8 @@
         goto error;
 
     if (buffering) {
-        raw = PyObject_GetAttrString(buf, "raw");
+        _Py_identifier(raw);
+        raw = _PyObject_GetAttrId(buf, &PyId_raw);
         if (raw == NULL)
             goto error;
     }
@@ -1115,13 +1117,14 @@
     PyArena *arena;
     char *ps1 = "", *ps2 = "", *enc = NULL;
     int errcode = 0;
+    _Py_identifier(encoding);
 
     if (fp == stdin) {
         /* Fetch encoding from sys.stdin */
         v = PySys_GetObject("stdin");
         if (v == NULL || v == Py_None)
             return -1;
-        oenc = PyObject_GetAttrString(v, "encoding");
+        oenc = _PyObject_GetAttrId(v, &PyId_encoding);
         if (!oenc)
             return -1;
         enc = _PyUnicode_AsString(oenc);
@@ -1318,6 +1321,11 @@
 {
     long hold;
     PyObject *v;
+    _Py_identifier(msg);
+    _Py_identifier(filename);
+    _Py_identifier(lineno);
+    _Py_identifier(offset);
+    _Py_identifier(text);
 
     /* old style errors */
     if (PyTuple_Check(err))
@@ -1326,11 +1334,11 @@
 
     /* new style errors.  `err' is an instance */
 
-    if (! (v = PyObject_GetAttrString(err, "msg")))
+    if (! (v = _PyObject_GetAttrId(err, &PyId_msg)))
         goto finally;
     *message = v;
 
-    if (!(v = PyObject_GetAttrString(err, "filename")))
+    if (!(v = _PyObject_GetAttrId(err, &PyId_filename)))
         goto finally;
     if (v == Py_None)
         *filename = NULL;
@@ -1338,7 +1346,7 @@
         goto finally;
 
     Py_DECREF(v);
-    if (!(v = PyObject_GetAttrString(err, "lineno")))
+    if (!(v = _PyObject_GetAttrId(err, &PyId_lineno)))
         goto finally;
     hold = PyLong_AsLong(v);
     Py_DECREF(v);
@@ -1347,7 +1355,7 @@
         goto finally;
     *lineno = (int)hold;
 
-    if (!(v = PyObject_GetAttrString(err, "offset")))
+    if (!(v = _PyObject_GetAttrId(err, &PyId_offset)))
         goto finally;
     if (v == Py_None) {
         *offset = -1;
@@ -1362,7 +1370,7 @@
         *offset = (int)hold;
     }
 
-    if (!(v = PyObject_GetAttrString(err, "text")))
+    if (!(v = _PyObject_GetAttrId(err, &PyId_text)))
         goto finally;
     if (v == Py_None)
         *text = NULL;
@@ -1431,7 +1439,8 @@
         goto done;
     if (PyExceptionInstance_Check(value)) {
         /* The error code should be in the `code' attribute. */
-        PyObject *code = PyObject_GetAttrString(value, "code");
+        _Py_identifier(code);
+        PyObject *code = _PyObject_GetAttrId(value, &PyId_code);
         if (code) {
             Py_DECREF(value);
             value = code;
@@ -1588,6 +1597,7 @@
     else {
         PyObject* moduleName;
         char* className;
+        _Py_identifier(__module__);
         assert(PyExceptionClass_Check(type));
         className = PyExceptionClass_Name(type);
         if (className != NULL) {
@@ -1596,7 +1606,7 @@
                 className = dot+1;
         }
 
-        moduleName = PyObject_GetAttrString(type, "__module__");
+        moduleName = _PyObject_GetAttrId(type, &PyId___module__);
         if (moduleName == NULL || !PyUnicode_Check(moduleName))
         {
             Py_XDECREF(moduleName);
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -79,8 +79,10 @@
     PyObject *encoded, *escaped_str, *repr_str, *buffer, *result;
     char *stdout_encoding_str;
     int ret;
+    _Py_identifier(encoding);
+    _Py_identifier(buffer);
 
-    stdout_encoding = PyObject_GetAttrString(outf, "encoding");
+    stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding);
     if (stdout_encoding == NULL)
         goto error;
     stdout_encoding_str = _PyUnicode_AsString(stdout_encoding);
@@ -97,7 +99,7 @@
     if (encoded == NULL)
         goto error;
 
-    buffer = PyObject_GetAttrString(outf, "buffer");
+    buffer = _PyObject_GetAttrId(outf, &PyId_buffer);
     if (buffer) {
         _Py_identifier(write);
         result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded);
@@ -1841,11 +1843,12 @@
 {
     PyObject *writer = NULL, *args = NULL, *result = NULL;
     int err;
+    _Py_identifier(write);
 
     if (file == NULL)
         return -1;
 
-    writer = PyObject_GetAttrString(file, "write");
+    writer = _PyObject_GetAttrId(file, &PyId_write);
     if (writer == NULL)
         goto error;
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list