Add API for static strings, primarily good for identifiers.
Thanks to Konrad Schöbel and Jasper Schulz for helping with the mass-editing.
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 6f5bd48..f264756 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -308,6 +308,9 @@
 
     PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL;
 
+    _Py_identifier(isatty);
+    _Py_identifier(fileno);
+
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist,
                                      &file, &mode, &buffering,
                                      &encoding, &errors, &newline,
@@ -421,7 +424,7 @@
 
     /* buffering */
     {
-        PyObject *res = PyObject_CallMethod(raw, "isatty", NULL);
+        PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
         if (res == NULL)
             goto error;
         isatty = PyLong_AsLong(res);
@@ -443,7 +446,7 @@
         {
             struct stat st;
             long fileno;
-            PyObject *res = PyObject_CallMethod(raw, "fileno", NULL);
+            PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL);
             if (res == NULL)
                 goto error;
 
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 86f7412..6ef2c20 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -13,6 +13,18 @@
 #include "pythread.h"
 #include "_iomodule.h"
 
+_Py_identifier(close);
+_Py_identifier(_dealloc_warn);
+_Py_identifier(flush);
+_Py_identifier(isatty);
+_Py_identifier(peek);
+_Py_identifier(read);
+_Py_identifier(read1);
+_Py_identifier(readable);
+_Py_identifier(readinto);
+_Py_identifier(writable);
+_Py_identifier(write);
+
 /*
  * BufferedIOBase class, inherits from IOBase.
  */
@@ -38,12 +50,13 @@
     Py_buffer buf;
     Py_ssize_t len;
     PyObject *data;
+    _Py_identifier(read);
 
     if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
         return NULL;
     }
 
-    data = PyObject_CallMethod(self, "read", "n", buf.len);
+    data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
     if (data == NULL)
         goto error;
 
@@ -410,7 +423,7 @@
 {
     if (self->ok && self->raw) {
         PyObject *r;
-        r = PyObject_CallMethod(self->raw, "_dealloc_warn", "O", source);
+        r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
         if (r)
             Py_DECREF(r);
         else
@@ -2216,13 +2229,13 @@
 }
 
 static PyObject *
-_forward_call(buffered *self, const char *name, PyObject *args)
+_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
 {
-    PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
+    PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
     PyObject *ret;
 
     if (func == NULL) {
-        PyErr_SetString(PyExc_AttributeError, name);
+        PyErr_SetString(PyExc_AttributeError, name->string);
         return NULL;
     }
 
@@ -2234,66 +2247,66 @@
 static PyObject *
 bufferedrwpair_read(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->reader, "read", args);
+    return _forward_call(self->reader, &PyId_read, args);
 }
 
 static PyObject *
 bufferedrwpair_peek(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->reader, "peek", args);
+    return _forward_call(self->reader, &PyId_peek, args);
 }
 
 static PyObject *
 bufferedrwpair_read1(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->reader, "read1", args);
+    return _forward_call(self->reader, &PyId_read1, args);
 }
 
 static PyObject *
 bufferedrwpair_readinto(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->reader, "readinto", args);
+    return _forward_call(self->reader, &PyId_readinto, args);
 }
 
 static PyObject *
 bufferedrwpair_write(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->writer, "write", args);
+    return _forward_call(self->writer, &PyId_write, args);
 }
 
 static PyObject *
 bufferedrwpair_flush(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->writer, "flush", args);
+    return _forward_call(self->writer, &PyId_flush, args);
 }
 
 static PyObject *
 bufferedrwpair_readable(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->reader, "readable", args);
+    return _forward_call(self->reader, &PyId_readable, args);
 }
 
 static PyObject *
 bufferedrwpair_writable(rwpair *self, PyObject *args)
 {
-    return _forward_call(self->writer, "writable", args);
+    return _forward_call(self->writer, &PyId_writable, args);
 }
 
 static PyObject *
 bufferedrwpair_close(rwpair *self, PyObject *args)
 {
-    PyObject *ret = _forward_call(self->writer, "close", args);
+    PyObject *ret = _forward_call(self->writer, &PyId_close, args);
     if (ret == NULL)
         return NULL;
     Py_DECREF(ret);
 
-    return _forward_call(self->reader, "close", args);
+    return _forward_call(self->reader, &PyId_close, args);
 }
 
 static PyObject *
 bufferedrwpair_isatty(rwpair *self, PyObject *args)
 {
-    PyObject *ret = _forward_call(self->writer, "isatty", args);
+    PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
 
     if (ret != Py_False) {
         /* either True or exception */
@@ -2301,7 +2314,7 @@
     }
     Py_DECREF(ret);
 
-    return _forward_call(self->reader, "isatty", args);
+    return _forward_call(self->reader, &PyId_isatty, args);
 }
 
 static PyObject *
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 2bf8933..a16d13c 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -128,6 +128,7 @@
 static PyObject *
 fileio_close(fileio *self)
 {
+    _Py_identifier(close);
     if (!self->closefd) {
         self->fd = -1;
         Py_RETURN_NONE;
@@ -143,8 +144,8 @@
     if (errno < 0)
         return NULL;
 
-    return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type,
-                               "close", "O", self);
+    return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type,
+                                  &PyId_close, "O", self);
 }
 
 static PyObject *
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 35c7cdd..6a94a04 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -97,7 +97,9 @@
 static PyObject *
 iobase_tell(PyObject *self, PyObject *args)
 {
-    return PyObject_CallMethod(self, "seek", "ii", 0, 1);
+    _Py_identifier(seek);
+
+    return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1);
 }
 
 PyDoc_STRVAR(iobase_truncate_doc,
@@ -464,6 +466,7 @@
     int has_peek = 0;
     PyObject *buffer, *result;
     Py_ssize_t old_size = -1;
+    _Py_identifier(read);
 
     if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
         return NULL;
@@ -481,7 +484,9 @@
         PyObject *b;
 
         if (has_peek) {
-            PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
+            _Py_identifier(peek);
+            PyObject *readahead = _PyObject_CallMethodId(self, &PyId_peek, "i", 1);
+
             if (readahead == NULL)
                 goto fail;
             if (!PyBytes_Check(readahead)) {
@@ -515,7 +520,7 @@
             Py_DECREF(readahead);
         }
 
-        b = PyObject_CallMethod(self, "read", "n", nreadahead);
+        b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead);
         if (b == NULL)
             goto fail;
         if (!PyBytes_Check(b)) {
@@ -601,7 +606,9 @@
         /* XXX special-casing this made sense in the Python version in order
            to remove the bytecode interpretation overhead, but it could
            probably be removed here. */
-        PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
+        _Py_identifier(extend);
+        PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self);
+
         if (ret == NULL) {
             Py_DECREF(result);
             return NULL;
@@ -781,8 +788,11 @@
         return NULL;
     }
 
-    if (n < 0)
-        return PyObject_CallMethod(self, "readall", NULL);
+    if (n < 0) {
+        _Py_identifier(readall);
+
+        return _PyObject_CallMethodId(self, &PyId_readall, NULL);
+    }
 
     /* TODO: allocate a bytes object directly instead and manually construct
        a writable memoryview pointing to it. */
@@ -823,8 +833,9 @@
         return NULL;
 
     while (1) {
-        PyObject *data = PyObject_CallMethod(self, "read",
-                                             "i", DEFAULT_BUFFER_SIZE);
+        _Py_identifier(read);
+        PyObject *data = _PyObject_CallMethodId(self, &PyId_read,
+                                                "i", DEFAULT_BUFFER_SIZE);
         if (!data) {
             Py_DECREF(chunks);
             return NULL;
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index aa29ffb..2ded719 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -11,6 +11,24 @@
 #include "structmember.h"
 #include "_iomodule.h"
 
+_Py_identifier(close);
+_Py_identifier(_dealloc_warn);
+_Py_identifier(decode);
+_Py_identifier(device_encoding);
+_Py_identifier(fileno);
+_Py_identifier(flush);
+_Py_identifier(getpreferredencoding);
+_Py_identifier(isatty);
+_Py_identifier(read);
+_Py_identifier(readable);
+_Py_identifier(replace);
+_Py_identifier(reset);
+_Py_identifier(seek);
+_Py_identifier(seekable);
+_Py_identifier(setstate);
+_Py_identifier(tell);
+_Py_identifier(writable);
+
 /* TextIOBase */
 
 PyDoc_STRVAR(textiobase_doc,
@@ -501,8 +519,8 @@
     flag >>= 1;
 
     if (self->decoder != Py_None)
-        return PyObject_CallMethod(self->decoder,
-                                   "setstate", "((OK))", buffer, flag);
+        return _PyObject_CallMethodId(self->decoder,
+                                      &PyId_setstate, "((OK))", buffer, flag);
     else
         Py_RETURN_NONE;
 }
@@ -842,7 +860,7 @@
     if (encoding == NULL) {
         /* Try os.device_encoding(fileno) */
         PyObject *fileno;
-        fileno = PyObject_CallMethod(buffer, "fileno", NULL);
+        fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL);
         /* Ignore only AttributeError and UnsupportedOperation */
         if (fileno == NULL) {
             if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
@@ -854,9 +872,9 @@
             }
         }
         else {
-            self->encoding = PyObject_CallMethod(state->os_module,
-                                                 "device_encoding",
-                                                 "N", fileno);
+            self->encoding = _PyObject_CallMethodId(state->os_module,
+                                                    &PyId_device_encoding,
+                                                    "N", fileno);
             if (self->encoding == NULL)
                 goto error;
             else if (!PyUnicode_Check(self->encoding))
@@ -873,8 +891,8 @@
         }
         else {
           use_locale:
-            self->encoding = PyObject_CallMethod(
-                state->locale_module, "getpreferredencoding", NULL);
+            self->encoding = _PyObject_CallMethodId(
+                state->locale_module, &PyId_getpreferredencoding, NULL);
             if (self->encoding == NULL) {
               catch_ImportError:
                 /*
@@ -939,7 +957,7 @@
 #endif
 
     /* Build the decoder object */
-    res = PyObject_CallMethod(buffer, "readable", NULL);
+    res = _PyObject_CallMethodId(buffer, &PyId_readable, NULL);
     if (res == NULL)
         goto error;
     r = PyObject_IsTrue(res);
@@ -964,7 +982,7 @@
     }
 
     /* Build the encoder object */
-    res = PyObject_CallMethod(buffer, "writable", NULL);
+    res = _PyObject_CallMethodId(buffer, &PyId_writable, NULL);
     if (res == NULL)
         goto error;
     r = PyObject_IsTrue(res);
@@ -1022,7 +1040,7 @@
             Py_DECREF(raw);
     }
 
-    res = PyObject_CallMethod(buffer, "seekable", NULL);
+    res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
     if (res == NULL)
         goto error;
     self->seekable = self->telling = PyObject_IsTrue(res);
@@ -1255,8 +1273,8 @@
             haslf = 1;
 
     if (haslf && self->writetranslate && self->writenl != NULL) {
-        PyObject *newtext = PyObject_CallMethod(
-            text, "replace", "ss", "\n", self->writenl);
+        PyObject *newtext = _PyObject_CallMethodId(
+            text, &PyId_replace, "ss", "\n", self->writenl);
         Py_DECREF(text);
         if (newtext == NULL)
             return NULL;
@@ -1311,7 +1329,7 @@
     Py_CLEAR(self->snapshot);
 
     if (self->decoder) {
-        ret = PyObject_CallMethod(self->decoder, "reset", NULL);
+        ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
         if (ret == NULL)
             return NULL;
         Py_DECREF(ret);
@@ -1490,7 +1508,7 @@
 
     if (n < 0) {
         /* Read everything */
-        PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
+        PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL);
         PyObject *decoded;
         if (bytes == NULL)
             goto fail;
@@ -1940,8 +1958,8 @@
     if (cookie->start_pos == 0 && cookie->dec_flags == 0)
         res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
     else
-        res = PyObject_CallMethod(self->decoder, "setstate",
-                                  "((yi))", "", cookie->dec_flags);
+        res = _PyObject_CallMethodId(self->decoder, &PyId_setstate,
+                                     "((yi))", "", cookie->dec_flags);
     if (res == NULL)
         return -1;
     Py_DECREF(res);
@@ -2005,13 +2023,12 @@
          * sync the underlying buffer with the current position.
          */
         Py_DECREF(cookieObj);
-        cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
+        cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL);
         if (cookieObj == NULL)
             goto fail;
     }
     else if (whence == 2) {
         /* seek relative to end of file */
-
         cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
         if (cmp < 0)
             goto fail;
@@ -2021,7 +2038,7 @@
             goto fail;
         }
 
-        res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+        res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
         if (res == NULL)
             goto fail;
         Py_DECREF(res);
@@ -2029,13 +2046,13 @@
         textiowrapper_set_decoded_chars(self, NULL);
         Py_CLEAR(self->snapshot);
         if (self->decoder) {
-            res = PyObject_CallMethod(self->decoder, "reset", NULL);
+            res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
             if (res == NULL)
                 goto fail;
             Py_DECREF(res);
         }
 
-        res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
+        res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2);
         Py_XDECREF(cookieObj);
         return res;
     }
@@ -2088,8 +2105,8 @@
 
     if (cookie.chars_to_skip) {
         /* Just like _read_chunk, feed the decoder and save a snapshot. */
-        PyObject *input_chunk = PyObject_CallMethod(
-            self->buffer, "read", "i", cookie.bytes_to_feed);
+        PyObject *input_chunk = _PyObject_CallMethodId(
+            self->buffer, &PyId_read, "i", cookie.bytes_to_feed);
         PyObject *decoded;
 
         if (input_chunk == NULL)
@@ -2103,8 +2120,8 @@
             goto fail;
         }
 
-        decoded = PyObject_CallMethod(self->decoder, "decode",
-                                      "Oi", input_chunk, (int)cookie.need_eof);
+        decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode,
+            "Oi", input_chunk, (int)cookie.need_eof);
 
         if (decoded == NULL)
             goto fail;
@@ -2170,12 +2187,12 @@
 
     if (_textiowrapper_writeflush(self) < 0)
         return NULL;
-    res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+    res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
     if (res == NULL)
         goto fail;
     Py_DECREF(res);
 
-    posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
+    posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL);
     if (posobj == NULL)
         goto fail;
 
@@ -2229,8 +2246,8 @@
 
     /* TODO: replace assert with exception */
 #define DECODER_DECODE(start, len, res) do { \
-        PyObject *_decoded = PyObject_CallMethod( \
-            self->decoder, "decode", "y#", start, len); \
+        PyObject *_decoded = _PyObject_CallMethodId( \
+            self->decoder, &PyId_decode, "y#", start, len); \
         if (_decoded == NULL) \
             goto fail; \
         assert (PyUnicode_Check(_decoded)); \
@@ -2312,8 +2329,8 @@
     }
     if (input == input_end) {
         /* We didn't get enough decoded data; signal EOF to get more. */
-        PyObject *decoded = PyObject_CallMethod(
-            self->decoder, "decode", "yi", "", /* final = */ 1);
+        PyObject *decoded = _PyObject_CallMethodId(
+            self->decoder, &PyId_decode, "yi", "", /* final = */ 1);
         if (decoded == NULL)
             goto fail;
         assert (PyUnicode_Check(decoded));
@@ -2329,7 +2346,7 @@
     }
 
 finally:
-    res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
+    res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state);
     Py_DECREF(saved_state);
     if (res == NULL)
         return NULL;
@@ -2344,7 +2361,7 @@
         PyObject *type, *value, *traceback;
         PyErr_Fetch(&type, &value, &traceback);
 
-        res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
+        res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state);
         Py_DECREF(saved_state);
         if (res == NULL)
             return NULL;
@@ -2432,35 +2449,35 @@
 textiowrapper_fileno(textio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
-    return PyObject_CallMethod(self->buffer, "fileno", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
 }
 
 static PyObject *
 textiowrapper_seekable(textio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
-    return PyObject_CallMethod(self->buffer, "seekable", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
 }
 
 static PyObject *
 textiowrapper_readable(textio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
-    return PyObject_CallMethod(self->buffer, "readable", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
 }
 
 static PyObject *
 textiowrapper_writable(textio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
-    return PyObject_CallMethod(self->buffer, "writable", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
 }
 
 static PyObject *
 textiowrapper_isatty(textio *self, PyObject *args)
 {
     CHECK_INITIALIZED(self);
-    return PyObject_CallMethod(self->buffer, "isatty", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
 }
 
 static PyObject *
@@ -2479,7 +2496,7 @@
     self->telling = self->seekable;
     if (_textiowrapper_writeflush(self) < 0)
         return NULL;
-    return PyObject_CallMethod(self->buffer, "flush", NULL);
+    return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL);
 }
 
 static PyObject *
@@ -2502,20 +2519,20 @@
     }
     else {
         if (self->deallocating) {
-            res = PyObject_CallMethod(self->buffer, "_dealloc_warn", "O", self);
+            res = _PyObject_CallMethodId(self->buffer, &PyId__dealloc_warn, "O", self);
             if (res)
                 Py_DECREF(res);
             else
                 PyErr_Clear();
         }
-        res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+        res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
         if (res == NULL) {
             return NULL;
         }
         else
             Py_DECREF(res);
 
-        return PyObject_CallMethod(self->buffer, "close", NULL);
+        return _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
     }
 }