Add more checks on the GIL

Issue #10915, #15751, #26558:

* PyGILState_Check() now returns 1 (success) before the creation of the GIL and
  after the destruction of the GIL. It allows to use the function early in
  Python initialization and late in Python finalization.
* Add a flag to disable PyGILState_Check(). Disable PyGILState_Check() when
  Py_NewInterpreter() is called
* Add assert(PyGILState_Check()) to: _Py_dup(), _Py_fstat(), _Py_read()
  and _Py_write()
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 06d632a..a710c99 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -683,6 +683,10 @@
 {
     int res;
 
+#ifdef WITH_THREAD
+    assert(PyGILState_Check());
+#endif
+
     Py_BEGIN_ALLOW_THREADS
     res = _Py_fstat_noraise(fd, status);
     Py_END_ALLOW_THREADS
@@ -1164,6 +1168,10 @@
     int err;
     int async_err = 0;
 
+#ifdef WITH_THREAD
+    assert(PyGILState_Check());
+#endif
+
     /* _Py_read() must not be called with an exception set, otherwise the
      * caller may think that read() was interrupted by a signal and the signal
      * handler raised an exception. */
@@ -1319,6 +1327,10 @@
 Py_ssize_t
 _Py_write(int fd, const void *buf, size_t count)
 {
+#ifdef WITH_THREAD
+    assert(PyGILState_Check());
+#endif
+
     /* _Py_write() must not be called with an exception set, otherwise the
      * caller may think that write() was interrupted by a signal and the signal
      * handler raised an exception. */
@@ -1468,6 +1480,10 @@
     DWORD ftype;
 #endif
 
+#ifdef WITH_THREAD
+    assert(PyGILState_Check());
+#endif
+
     if (!_PyVerify_fd(fd)) {
         PyErr_SetFromErrno(PyExc_OSError);
         return -1;