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/Python/_warnings.c b/Python/_warnings.c
index 792e3ed..e563107 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -18,11 +18,12 @@
 check_matched(PyObject *obj, PyObject *arg)
 {
     PyObject *result;
+    _Py_identifier(match);
     int rc;
 
     if (obj == Py_None)
         return 1;
-    result = PyObject_CallMethod(obj, "match", "O", arg);
+    result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg);
     if (result == NULL)
         return -1;
 
diff --git a/Python/ast.c b/Python/ast.c
index a52fd09..9872979 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -527,6 +527,7 @@
 static identifier
 new_identifier(const char* n, PyArena *arena)
 {
+    _Py_identifier(normalize);
     PyObject* id = PyUnicode_DecodeUTF8(n, strlen(n), NULL);
     if (!id || PyUnicode_READY(id) == -1)
         return NULL;
@@ -537,7 +538,7 @@
         PyObject *id2;
         if (!m)
             return NULL;
-        id2 = PyObject_CallMethod(m, "normalize", "sO", "NFKC", id);
+        id2 = _PyObject_CallMethodId(m, &PyId_normalize, "sO", "NFKC", id);
         Py_DECREF(m);
         if (!id2)
             return NULL;
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 04f5231..c174e9d 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -32,6 +32,9 @@
 int Py_HasFileSystemDefaultEncoding = 0;
 #endif
 
+_Py_identifier(fileno);
+_Py_identifier(flush);
+
 static PyObject *
 builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
 {
@@ -1567,7 +1570,7 @@
     }
 
     /* First of all, flush stderr */
-    tmp = PyObject_CallMethod(ferr, "flush", "");
+    tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
     if (tmp == NULL)
         PyErr_Clear();
     else
@@ -1576,7 +1579,7 @@
     /* We should only use (GNU) readline if Python's sys.stdin and
        sys.stdout are the same as C's stdin and stdout, because we
        need to pass it those. */
-    tmp = PyObject_CallMethod(fin, "fileno", "");
+    tmp = _PyObject_CallMethodId(fin, &PyId_fileno, "");
     if (tmp == NULL) {
         PyErr_Clear();
         tty = 0;
@@ -1589,7 +1592,7 @@
         tty = fd == fileno(stdin) && isatty(fd);
     }
     if (tty) {
-        tmp = PyObject_CallMethod(fout, "fileno", "");
+        tmp = _PyObject_CallMethodId(fout, &PyId_fileno, "");
         if (tmp == NULL)
             PyErr_Clear();
         else {
@@ -1621,7 +1624,7 @@
             Py_DECREF(stdin_encoding);
             return NULL;
         }
-        tmp = PyObject_CallMethod(fout, "flush", "");
+        tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
         if (tmp == NULL)
             PyErr_Clear();
         else
@@ -1703,7 +1706,7 @@
         if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)
             return NULL;
     }
-    tmp = PyObject_CallMethod(fout, "flush", "");
+    tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
     if (tmp == NULL)
         PyErr_Clear();
     else
diff --git a/Python/ceval.c b/Python/ceval.c
index 686a54d..04d3df1 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -372,6 +372,7 @@
 void
 PyEval_ReInitThreads(void)
 {
+    _Py_identifier(_after_fork);
     PyObject *threading, *result;
     PyThreadState *tstate = PyThreadState_GET();
 
@@ -392,7 +393,7 @@
         PyErr_Clear();
         return;
     }
-    result = PyObject_CallMethod(threading, "_after_fork", NULL);
+    result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL);
     if (result == NULL)
         PyErr_WriteUnraisable(threading);
     else
diff --git a/Python/import.c b/Python/import.c
index 5f84ac2..6eca90a 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1801,6 +1801,7 @@
 
     /* sys.path_hooks import hook */
     if (p_loader != NULL) {
+        _Py_identifier(find_module);
         PyObject *importer;
 
         importer = get_path_importer(path_importer_cache,
@@ -1811,8 +1812,8 @@
         /* Note: importer is a borrowed reference */
         if (importer != Py_None) {
             PyObject *loader;
-            loader = PyObject_CallMethod(importer,
-                                         "find_module", "O", fullname);
+            loader = _PyObject_CallMethodId(importer,
+                                            &PyId_find_module, "O", fullname);
             if (loader == NULL)
                 return -1;  /* error */
             if (loader != Py_None) {
@@ -2030,6 +2031,7 @@
 
     /* sys.meta_path import hook */
     if (p_loader != NULL) {
+        _Py_identifier(find_module);
         PyObject *meta_path;
 
         meta_path = PySys_GetObject("meta_path");
@@ -2044,7 +2046,7 @@
         for (i = 0; i < npath; i++) {
             PyObject *loader;
             PyObject *hook = PyList_GetItem(meta_path, i);
-            loader = PyObject_CallMethod(hook, "find_module",
+            loader = _PyObject_CallMethodId(hook, &PyId_find_module,
                                          "OO", fullname,
                                          search_path_list != NULL ?
                                          search_path_list : Py_None);
@@ -2454,12 +2456,13 @@
         break;
 
     case IMP_HOOK: {
+        _Py_identifier(load_module);
         if (loader == NULL) {
             PyErr_SetString(PyExc_ImportError,
                             "import hook without loader");
             return NULL;
         }
-        m = PyObject_CallMethod(loader, "load_module", "O", name);
+        m = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
         break;
     }
 
diff --git a/Python/marshal.c b/Python/marshal.c
index 31fe66b..b8288d0 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -480,7 +480,9 @@
         }
     }
     else {
-        PyObject *data = PyObject_CallMethod(p->readable, "read", "i", n);
+        _Py_identifier(read);
+
+        PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "i", n);
         read = 0;
         if (data != NULL) {
             if (!PyBytes_Check(data)) {
@@ -1290,12 +1292,14 @@
     int version = Py_MARSHAL_VERSION;
     PyObject *s;
     PyObject *res;
+    _Py_identifier(write);
+
     if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
         return NULL;
     s = PyMarshal_WriteObjectToString(x, version);
     if (s == NULL)
         return NULL;
-    res = PyObject_CallMethod(f, "write", "O", s);
+    res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
     Py_DECREF(s);
     return res;
 }
@@ -1317,6 +1321,7 @@
 marshal_load(PyObject *self, PyObject *f)
 {
     PyObject *data, *result;
+    _Py_identifier(read);
     RFILE rf;
 
     /*
@@ -1324,7 +1329,7 @@
      * This is to ensure that the object passed in at least
      * has a read method which returns bytes.
      */
-    data = PyObject_CallMethod(f, "read", "i", 0);
+    data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
     if (data == NULL)
         return NULL;
     if (!PyBytes_Check(data)) {
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 1888fba..0ef36bb 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -352,9 +352,10 @@
     PyObject *fout = PySys_GetObject("stdout");
     PyObject *ferr = PySys_GetObject("stderr");
     PyObject *tmp;
+    _Py_identifier(flush);
 
     if (fout != NULL && fout != Py_None) {
-        tmp = PyObject_CallMethod(fout, "flush", "");
+        tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
         if (tmp == NULL)
             PyErr_WriteUnraisable(fout);
         else
@@ -362,7 +363,7 @@
     }
 
     if (ferr != NULL && ferr != Py_None) {
-        tmp = PyObject_CallMethod(ferr, "flush", "");
+        tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
         if (tmp == NULL)
             PyErr_Clear();
         else
@@ -805,6 +806,9 @@
     const char* newline;
     PyObject *line_buffering;
     int buffering, isatty;
+    _Py_identifier(open);
+    _Py_identifier(isatty);
+    _Py_identifier(TextIOWrapper);
 
     /* stdin is always opened in buffered mode, first because it shouldn't
        make a difference in common use cases, second because TextIOWrapper
@@ -819,9 +823,9 @@
         mode = "wb";
     else
         mode = "rb";
-    buf = PyObject_CallMethod(io, "open", "isiOOOi",
-                              fd, mode, buffering,
-                              Py_None, Py_None, Py_None, 0);
+    buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi",
+                                 fd, mode, buffering,
+                                 Py_None, Py_None, Py_None, 0);
     if (buf == NULL)
         goto error;
 
@@ -838,7 +842,7 @@
     text = PyUnicode_FromString(name);
     if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0)
         goto error;
-    res = PyObject_CallMethod(raw, "isatty", "");
+    res = _PyObject_CallMethodId(raw, &PyId_isatty, "");
     if (res == NULL)
         goto error;
     isatty = PyObject_IsTrue(res);
@@ -861,9 +865,9 @@
     }
 #endif
 
-    stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO",
-                                 buf, encoding, errors,
-                                 newline, line_buffering);
+    stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
+                                    buf, encoding, errors,
+                                    newline, line_buffering);
     Py_CLEAR(buf);
     if (stream == NULL)
         goto error;
@@ -1759,13 +1763,14 @@
 {
     PyObject *f, *r;
     PyObject *type, *value, *traceback;
+    _Py_identifier(flush);
 
     /* Save the current exception */
     PyErr_Fetch(&type, &value, &traceback);
 
     f = PySys_GetObject("stderr");
     if (f != NULL) {
-        r = PyObject_CallMethod(f, "flush", "");
+        r = _PyObject_CallMethodId(f, &PyId_flush, "");
         if (r)
             Py_DECREF(r);
         else
@@ -1773,7 +1778,7 @@
     }
     f = PySys_GetObject("stdout");
     if (f != NULL) {
-        r = PyObject_CallMethod(f, "flush", "");
+        r = _PyObject_CallMethodId(f, &PyId_flush, "");
         if (r)
             Py_DECREF(r);
         else
@@ -2205,6 +2210,7 @@
 wait_for_thread_shutdown(void)
 {
 #ifdef WITH_THREAD
+    _Py_identifier(_shutdown);
     PyObject *result;
     PyThreadState *tstate = PyThreadState_GET();
     PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
@@ -2214,7 +2220,7 @@
         PyErr_Clear();
         return;
     }
-    result = PyObject_CallMethod(threading, "_shutdown", "");
+    result = _PyObject_CallMethodId(threading, &PyId__shutdown, "");
     if (result == NULL) {
         PyErr_WriteUnraisable(threading);
     }
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 3576ced..f0acead 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -99,7 +99,8 @@
 
     buffer = PyObject_GetAttrString(outf, "buffer");
     if (buffer) {
-        result = PyObject_CallMethod(buffer, "write", "(O)", encoded);
+        _Py_identifier(write);
+        result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded);
         Py_DECREF(buffer);
         Py_DECREF(encoded);
         if (result == NULL)
diff --git a/Python/traceback.c b/Python/traceback.c
index b66c96c..551f9d6 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -152,6 +152,7 @@
     const char* filepath;
     Py_ssize_t len;
     PyObject* result;
+    _Py_identifier(open);
 
     filebytes = PyUnicode_EncodeFSDefault(filename);
     if (filebytes == NULL) {
@@ -199,7 +200,7 @@
             namebuf[len++] = SEP;
         strcpy(namebuf+len, tail);
 
-        binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb");
+        binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
         if (binary != NULL) {
             result = binary;
             goto finally;
@@ -231,6 +232,9 @@
     char buf[MAXPATHLEN+1];
     int kind;
     void *data;
+    _Py_identifier(close);
+    _Py_identifier(open);
+    _Py_identifier(TextIOWrapper);
 
     /* open the file */
     if (filename == NULL)
@@ -239,7 +243,7 @@
     io = PyImport_ImportModuleNoBlock("io");
     if (io == NULL)
         return -1;
-    binary = PyObject_CallMethod(io, "open", "Os", filename, "rb");
+    binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
 
     if (binary == NULL) {
         binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
@@ -254,7 +258,7 @@
     found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
     encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
     lseek(fd, 0, 0); /* Reset position */
-    fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding);
+    fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
     Py_DECREF(io);
     Py_DECREF(binary);
     PyMem_FREE(found_encoding);
@@ -273,7 +277,7 @@
             break;
         }
     }
-    res = PyObject_CallMethod(fob, "close", "");
+    res = _PyObject_CallMethodId(fob, &PyId_close, "");
     if (res)
         Py_DECREF(res);
     else