Issue #16719: Get rid of WindowsError. Use OSError instead

Patch by Serhiy Storchaka.
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index c92e130..e2f75c5 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -395,7 +395,7 @@
         _type_ = "l"
         # _check_retval_ is called with the function's result when it
         # is used as restype.  It checks for the FAILED bit, and
-        # raises a WindowsError if it is set.
+        # raises an OSError if it is set.
         #
         # The _check_retval_ method is implemented in C, so that the
         # method definition itself is not included in the traceback
@@ -407,7 +407,7 @@
     class OleDLL(CDLL):
         """This class represents a dll exporting functions using the
         Windows stdcall calling convention, and returning HRESULT.
-        HRESULT error values are automatically raised as WindowsError
+        HRESULT error values are automatically raised as OSError
         exceptions.
         """
         _func_flags_ = _FUNCFLAG_STDCALL
@@ -456,7 +456,7 @@
             code = GetLastError()
         if descr is None:
             descr = FormatError(code).strip()
-        return WindowsError(None, descr, None, code)
+        return OSError(None, descr, None, code)
 
 if sizeof(c_uint) == sizeof(c_void_p):
     c_size_t = c_uint
diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py
index 01ccc57..19bb813 100644
--- a/Lib/ctypes/test/test_checkretval.py
+++ b/Lib/ctypes/test/test_checkretval.py
@@ -31,7 +31,7 @@
         pass
     else:
         def test_oledll(self):
-            self.assertRaises(WindowsError,
+            self.assertRaises(OSError,
                                   oledll.oleaut32.CreateTypeLib2,
                                   0, None, None)
 
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index 128914e..4c85825 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -40,7 +40,7 @@
                 # Call functions with invalid arguments, and make sure
                 # that access violations are trapped and raise an
                 # exception.
-                self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
+                self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32)
 
         def test_noargs(self):
             # This is a special case on win32 x64
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index e74b619..4908705 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -536,7 +536,7 @@
         if sys.platform[:3] == 'win':
             try:
                 os.startfile(self.help_url)
-            except WindowsError as why:
+            except OSError as why:
                 tkMessageBox.showerror(title='Document Start Failure',
                     message=str(why), parent=self.text)
         else:
@@ -845,7 +845,7 @@
             if sys.platform[:3] == 'win':
                 try:
                     os.startfile(helpfile)
-                except WindowsError as why:
+                except OSError as why:
                     tkMessageBox.showerror(title='Document Start Failure',
                         message=str(why), parent=self.text)
             else:
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index 0c6252e..3ea798d 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -755,7 +755,7 @@
     def _open_registry(cls, key):
         try:
             return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
-        except WindowsError:
+        except OSError:
             return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
 
     @classmethod
@@ -769,7 +769,7 @@
         try:
             with cls._open_registry(key) as hkey:
                 filepath = _winreg.QueryValue(hkey, "")
-        except WindowsError:
+        except OSError:
             return None
         return filepath
 
diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py
index fbbd5d9..391d6b2 100644
--- a/Lib/multiprocessing/connection.py
+++ b/Lib/multiprocessing/connection.py
@@ -676,7 +676,7 @@
                     0, _winapi.NULL, _winapi.OPEN_EXISTING,
                     _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL
                     )
-            except WindowsError as e:
+            except OSError as e:
                 if e.winerror not in (_winapi.ERROR_SEM_TIMEOUT,
                                       _winapi.ERROR_PIPE_BUSY) or _check_timeout(t):
                     raise
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 12494c5..2fbb6d69 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -331,7 +331,7 @@
     """Test whether a path exists.  Returns True for broken symbolic links"""
     try:
         st = os.lstat(path)
-    except (OSError, WindowsError):
+    except OSError:
         return False
     return True
 
@@ -584,7 +584,7 @@
         if path: # Empty path must return current working directory.
             try:
                 path = _getfullpathname(path)
-            except WindowsError:
+            except OSError:
                 pass # Bad path - return unchanged.
         elif isinstance(path, bytes):
             path = os.getcwdb()
diff --git a/Lib/platform.py b/Lib/platform.py
index 53182c6..143138d 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -581,7 +581,7 @@
                     # Discard any type that isn't REG_SZ
                     if type == REG_SZ and name.find("Server") != -1:
                         product_type = VER_NT_SERVER
-                except WindowsError:
+                except OSError:
                     # Use default of VER_NT_WORKSTATION
                     pass
 
diff --git a/Lib/shutil.py b/Lib/shutil.py
index 9a79f85..b1e3017 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -60,11 +60,6 @@
     and unpacking registeries fails"""
 
 
-try:
-    WindowsError
-except NameError:
-    WindowsError = None
-
 def copyfileobj(fsrc, fdst, length=16*1024):
     """copy data from file-like object fsrc to file-like object fdst"""
     while 1:
@@ -334,10 +329,8 @@
     try:
         copystat(src, dst)
     except OSError as why:
-        if WindowsError is not None and isinstance(why, WindowsError):
-            # Copying file access times may fail on Windows
-            pass
-        else:
+        # Copying file access times may fail on Windows
+        if why.winerror is None:
             errors.append((src, dst, str(why)))
     if errors:
         raise Error(errors)
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index c0ae8b1..a0f132e 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -56,9 +56,9 @@
 # os.symlink on Windows prior to 6.0 raises NotImplementedError
 symlink_exception = (AttributeError, NotImplementedError)
 try:
-    # WindowsError (1314) will be raised if the caller does not hold the
+    # OSError (winerror=1314) will be raised if the caller does not hold the
     # SeCreateSymbolicLinkPrivilege privilege
-    symlink_exception += (WindowsError,)
+    symlink_exception += (OSError,)
 except NameError:
     pass
 
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index f2a1ae3..be85a4c 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -2035,8 +2035,8 @@
     def test_invalid_code_page(self):
         self.assertRaises(ValueError, codecs.code_page_encode, -1, 'a')
         self.assertRaises(ValueError, codecs.code_page_decode, -1, b'a')
-        self.assertRaises(WindowsError, codecs.code_page_encode, 123, 'a')
-        self.assertRaises(WindowsError, codecs.code_page_decode, 123, b'a')
+        self.assertRaises(OSError, codecs.code_page_encode, 123, 'a')
+        self.assertRaises(OSError, codecs.code_page_decode, 123, b'a')
 
     def test_code_page_name(self):
         self.assertRaisesRegex(UnicodeEncodeError, 'cp932',
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index e3b7909..e341bc7 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -658,7 +658,7 @@
             m = mmap.mmap(f.fileno(), 0)
             f.close()
             try:
-                m.resize(0) # will raise WindowsError
+                m.resize(0) # will raise OSError
             except:
                 pass
             try:
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 4f86ef5..165a9bf 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -468,9 +468,9 @@
             # Verify that an open file can be stat'ed
             try:
                 os.stat(r"c:\pagefile.sys")
-            except WindowsError as e:
-                if e.errno == 2: # file does not exist; cannot run test
-                    return
+            except FileNotFoundError:
+                pass # file does not exist; cannot run test
+            except OSError as e:
                 self.fail("Could not stat pagefile.sys")
 
         @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
@@ -1042,27 +1042,27 @@
 
 class Win32ErrorTests(unittest.TestCase):
     def test_rename(self):
-        self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak")
+        self.assertRaises(OSError, os.rename, support.TESTFN, support.TESTFN+".bak")
 
     def test_remove(self):
-        self.assertRaises(WindowsError, os.remove, support.TESTFN)
+        self.assertRaises(OSError, os.remove, support.TESTFN)
 
     def test_chdir(self):
-        self.assertRaises(WindowsError, os.chdir, support.TESTFN)
+        self.assertRaises(OSError, os.chdir, support.TESTFN)
 
     def test_mkdir(self):
         f = open(support.TESTFN, "w")
         try:
-            self.assertRaises(WindowsError, os.mkdir, support.TESTFN)
+            self.assertRaises(OSError, os.mkdir, support.TESTFN)
         finally:
             f.close()
             os.unlink(support.TESTFN)
 
     def test_utime(self):
-        self.assertRaises(WindowsError, os.utime, support.TESTFN, None)
+        self.assertRaises(OSError, os.utime, support.TESTFN, None)
 
     def test_chmod(self):
-        self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0)
+        self.assertRaises(OSError, os.chmod, support.TESTFN, 0)
 
 class TestInvalidFD(unittest.TestCase):
     singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat",
diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 1100737..318937c 100644
--- a/Lib/test/test_winreg.py
+++ b/Lib/test/test_winreg.py
@@ -54,13 +54,13 @@
     def delete_tree(self, root, subkey):
         try:
             hkey = OpenKey(root, subkey, KEY_ALL_ACCESS)
-        except WindowsError:
+        except OSError:
             # subkey does not exist
             return
         while True:
             try:
                 subsubkey = EnumKey(hkey, 0)
-            except WindowsError:
+            except OSError:
                 # no more subkeys
                 break
             self.delete_tree(hkey, subsubkey)
@@ -176,7 +176,7 @@
         try:
             key = OpenKey(root_key, test_key_name)
             self.fail("Could open the non-existent key")
-        except WindowsError: # Use this error name this time
+        except OSError: # Use this error name this time
             pass
 
     def _test_all(self, root_key, subkeystr="sub_key"):
@@ -227,7 +227,7 @@
 
     def test_inexistant_remote_registry(self):
         connect = lambda: ConnectRegistry("abcdefghijkl", HKEY_CURRENT_USER)
-        self.assertRaises(WindowsError, connect)
+        self.assertRaises(OSError, connect)
 
     def testExpandEnvironmentStrings(self):
         r = ExpandEnvironmentStrings("%windir%\\test")
@@ -239,8 +239,8 @@
         try:
             with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as h:
                 self.assertNotEqual(h.handle, 0)
-                raise WindowsError
-        except WindowsError:
+                raise OSError
+        except OSError:
             self.assertEqual(h.handle, 0)
 
     def test_changing_value(self):
@@ -375,7 +375,7 @@
                 open_fail = lambda: OpenKey(HKEY_CURRENT_USER,
                                             test_reflect_key_name, 0,
                                             KEY_READ | KEY_WOW64_64KEY)
-                self.assertRaises(WindowsError, open_fail)
+                self.assertRaises(OSError, open_fail)
 
             # Now explicitly open the 64-bit version of the key
             with OpenKey(HKEY_CURRENT_USER, test_reflect_key_name, 0,
@@ -415,7 +415,7 @@
             open_fail = lambda: OpenKeyEx(HKEY_CURRENT_USER,
                                           test_reflect_key_name, 0,
                                           KEY_READ | KEY_WOW64_64KEY)
-            self.assertRaises(WindowsError, open_fail)
+            self.assertRaises(OSError, open_fail)
 
             # Make sure the 32-bit key is actually there
             with OpenKeyEx(HKEY_CURRENT_USER, test_reflect_key_name, 0,
diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py
index eb7f75f..61d864a 100644
--- a/Lib/test/test_winsound.py
+++ b/Lib/test/test_winsound.py
@@ -22,7 +22,7 @@
         key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER,
                 "AppEvents\Schemes\Apps\.Default\{0}\.Default".format(sound))
         return winreg.EnumValue(key, 0)[1] != ""
-    except WindowsError:
+    except OSError:
         return False
 
 class BeepTest(unittest.TestCase):
diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index 6757bc6..2ebd892 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -2573,7 +2573,7 @@
                         proxies['https'] = 'https://%s' % proxyServer
                         proxies['ftp'] = 'ftp://%s' % proxyServer
             internetSettings.Close()
-        except (WindowsError, ValueError, TypeError):
+        except (OSError, ValueError, TypeError):
             # Either registry key not found etc, or the value in an
             # unexpected format.
             # proxies already set up to be empty so nothing to do
@@ -2603,7 +2603,7 @@
             proxyOverride = str(winreg.QueryValueEx(internetSettings,
                                                      'ProxyOverride')[0])
             # ^^^^ Returned as Unicode but problems if not converted to ASCII
-        except WindowsError:
+        except OSError:
             return 0
         if not proxyEnable or not proxyOverride:
             return 0
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 691f7db..f1a071b 100644
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -534,7 +534,7 @@
         def open(self, url, new=0, autoraise=True):
             try:
                 os.startfile(url)
-            except WindowsError:
+            except OSError:
                 # [Error 22] No application is associated with the specified
                 # file for this operation: '<URL>'
                 return False