Issue #22221: Backported fixes from Python 3 (issue #18960).

* Now the source encoding declaration on the second line isn't effective if
  the first line contains anything except a comment.  This affects compile(),
  eval() and exec() too.

* IDLE now ignores the source encoding declaration on the second line if the
  first line contains anything except a comment.

* 2to3 and the findnocoding.py script now ignore the source encoding
  declaration on the second line if the first line contains anything except
  a comment.
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
index 3e4af53..d0e4a0e 100644
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -259,11 +259,25 @@
     char * cs;
     int r = 1;
 
-    if (tok->cont_line)
+    if (tok->cont_line) {
         /* It's a continuation line, so it can't be a coding spec. */
+        tok->read_coding_spec = 1;
         return 1;
+    }
     cs = get_coding_spec(line, size);
-    if (cs != NULL) {
+    if (!cs) {
+        Py_ssize_t i;
+        for (i = 0; i < size; i++) {
+            if (line[i] == '#' || line[i] == '\n' || line[i] == '\r')
+                break;
+            if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') {
+                /* Stop checking coding spec after a line containing
+                 * anything except a comment. */
+                tok->read_coding_spec = 1;
+                break;
+            }
+        }
+    } else {
         tok->read_coding_spec = 1;
         if (tok->encoding == NULL) {
             assert(tok->decoding_state == 1); /* raw */
@@ -688,7 +702,7 @@
     if (newl[0]) {
         if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl))
             return error_ret(tok);
-        if (tok->enc == NULL && newl[1]) {
+        if (tok->enc == NULL && !tok->read_coding_spec && newl[1]) {
             if (!check_coding_spec(newl[0]+1, newl[1] - newl[0],
                                    tok, buf_setreadl))
                 return error_ret(tok);