diff --git a/mercurial/scmwindows.py b/mercurial/scmwindows.py
--- a/mercurial/scmwindows.py
+++ b/mercurial/scmwindows.py
@@ -1,6 +1,5 @@
 from __future__ import absolute_import
 
-import _winreg
 import os
 
 from . import (
@@ -8,6 +7,12 @@ from . import (
     util,
 )
 
+try:
+    import _winreg as winreg
+    winreg.CloseKey
+except ImportError:
+    import winreg
+
 def systemrcpath():
     '''return default os-specific hgrc search path'''
     rcpath = []
@@ -23,7 +28,7 @@ def systemrcpath():
                 rcpath.append(os.path.join(progrcd, f))
     # else look for a system rcpath in the registry
     value = util.lookupreg('SOFTWARE\\Mercurial', None,
-                           _winreg.HKEY_LOCAL_MACHINE)
+                           winreg.HKEY_LOCAL_MACHINE)
     if not isinstance(value, str) or not value:
         return rcpath
     value = util.localpath(value)
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -7,7 +7,6 @@
 
 from __future__ import absolute_import
 
-import _winreg
 import errno
 import msvcrt
 import os
@@ -22,6 +21,12 @@ from . import (
     win32,
 )
 
+try:
+    import _winreg as winreg
+    winreg.CloseKey
+except ImportError:
+    import winreg
+
 executablepath = win32.executablepath
 getuser = win32.getuser
 hidewindow = win32.hidewindow
@@ -432,12 +437,12 @@ def lookupreg(key, valname=None, scope=N
     LOCAL_MACHINE).
     '''
     if scope is None:
-        scope = (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE)
+        scope = (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE)
     elif not isinstance(scope, (list, tuple)):
         scope = (scope,)
     for s in scope:
         try:
-            val = _winreg.QueryValueEx(_winreg.OpenKey(s, key), valname)[0]
+            val = winreg.QueryValueEx(winreg.OpenKey(s, key), valname)[0]
             # never let a Unicode string escape into the wild
             return encoding.tolocal(val.encode('UTF-8'))
         except EnvironmentError:
diff --git a/tests/test-check-py3-compat.t b/tests/test-check-py3-compat.t
--- a/tests/test-check-py3-compat.t
+++ b/tests/test-check-py3-compat.t
@@ -146,7 +146,7 @@
   mercurial/revlog.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/revset.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/scmutil.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
-  mercurial/scmwindows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
+  mercurial/scmwindows.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/similar.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/simplemerge.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/sshpeer.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
@@ -167,7 +167,7 @@
   mercurial/url.py: error importing: <TypeError> getattr(): attribute name must be string (error at util.py:*) (glob)
   mercurial/verify.py: error importing: <TypeError> attribute name must be string, not 'bytes' (error at mdiff.py:*) (glob)
   mercurial/win32.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
-  mercurial/windows.py: error importing module: <ImportError> No module named '_winreg' (line *) (glob)
+  mercurial/windows.py: error importing module: <ImportError> No module named 'msvcrt' (line *) (glob)
   mercurial/wireproto.py: error importing module: <TypeError> a bytes-like object is required, not 'str' (line *) (glob)
 
 #endif