[pypy-commit] pypy py3.5: merge py3-winreg which uses unicode strings in winreg module

mattip pypy.commits at gmail.com
Sun Jan 7 16:08:09 EST 2018


Author: Matti Picus <matti.picus at gmail.com>
Branch: py3.5
Changeset: r93633:7b9edeb55281
Date: 2018-01-07 22:29 +0200
http://bitbucket.org/pypy/pypy/changeset/7b9edeb55281/

Log:	merge py3-winreg which uses unicode strings in winreg module

diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -171,6 +171,9 @@
     def visit_text0(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
+    def visit_unicode(self, el, app_sig):
+        self.checked_space_method(el, app_sig)
+
     def visit_fsencode(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
@@ -320,6 +323,9 @@
     def visit_text0(self, typ):
         self.run_args.append("space.text0_w(%s)" % (self.scopenext(),))
 
+    def visit_unicode(self, typ):
+        self.run_args.append("space.unicode_w(%s)" % (self.scopenext(),))
+
     def visit_fsencode(self, typ):
         self.run_args.append("space.fsencode_w(%s)" % (self.scopenext(),))
 
@@ -485,6 +491,9 @@
     def visit_text(self, typ):
         self.unwrap.append("space.text_w(%s)" % (self.nextarg(),))
 
+    def visit_unicode(self, typ):
+        self.unwrap.append("space.unicode_w(%s)" % (self.nextarg(),))
+
     def visit_text0(self, typ):
         self.unwrap.append("space.text0_w(%s)" % (self.nextarg(),))
 
diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py
--- a/pypy/module/_winreg/interp_winreg.py
+++ b/pypy/module/_winreg/interp_winreg.py
@@ -9,9 +9,10 @@
 
 def raiseWindowsError(space, errcode, context):
     message = rwin32.FormatErrorW(errcode)
+    w_errcode = space.newint(errcode)
     raise OperationError(space.w_WindowsError,
-                         space.newtuple([space.newint(errcode),
-                                         space.newunicode(message)]))
+                         space.newtuple([w_errcode, space.newunicode(message),
+                                        space.w_None, w_errcode]))
 
 class W_HKEY(W_Root):
     def __init__(self, space, hkey):
@@ -32,7 +33,7 @@
         return space.newint(self.as_int())
 
     def descr_repr(self, space):
-        return space.newtext("<PyHKEY:0x%x>" % (self.as_int(),))
+        return space.newunicode(u"<PyHKEY:0x%x>" % (self.as_int(),))
 
     def descr_int(self, space):
         return space.newint(self.as_int())
@@ -149,7 +150,7 @@
         if ret != 0:
             raiseWindowsError(space, ret, 'RegFlushKey')
 
- at unwrap_spec(subkey="text", filename="text")
+ at unwrap_spec(subkey="unicode", filename="unicode")
 def LoadKey(space, w_hkey, subkey, filename):
     """LoadKey(key, sub_key, file_name) - Creates a subkey under the specified key
 and stores registration information from a specified file into that subkey.
@@ -170,11 +171,15 @@
 The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"""
     # XXX should filename use space.fsencode_w?
     hkey = hkey_w(w_hkey, space)
-    ret = rwinreg.RegLoadKey(hkey, subkey, filename)
-    if ret != 0:
-        raiseWindowsError(space, ret, 'RegLoadKey')
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        with rffi.scoped_unicode2wcharp(filename) as wide_filename:
+            c_filename = rffi.cast(rffi.CCHARP, wide_filename)
+            ret = rwinreg.RegLoadKey(hkey, c_subkey, c_filename)
+            if ret != 0:
+                raiseWindowsError(space, ret, 'RegLoadKey')
 
- at unwrap_spec(filename="text")
+ at unwrap_spec(filename="unicode")
 def SaveKey(space, w_hkey, filename):
     """SaveKey(key, file_name) - Saves the specified key, and all its subkeys to the specified file.
 
@@ -189,11 +194,13 @@
 The caller of this method must possess the SeBackupPrivilege security privilege.
 This function passes NULL for security_attributes to the API."""
     hkey = hkey_w(w_hkey, space)
-    ret = rwinreg.RegSaveKey(hkey, filename, None)
-    if ret != 0:
-        raiseWindowsError(space, ret, 'RegSaveKey')
+    with rffi.scoped_unicode2wcharp(filename) as wide_filename:
+        c_filename = rffi.cast(rffi.CCHARP, wide_filename)
+        ret = rwinreg.RegSaveKey(hkey, c_filename, None)
+        if ret != 0:
+            raiseWindowsError(space, ret, 'RegSaveKey')
 
- at unwrap_spec(typ=int, value="text")
+ at unwrap_spec(typ=int, value="unicode")
 def SetValue(space, w_hkey, w_subkey, typ, value):
     """SetValue(key, sub_key, type, value) - Associates a value with a specified key.
 
@@ -215,14 +222,14 @@
     if typ != rwinreg.REG_SZ:
         raise oefmt(space.w_ValueError, "Type must be winreg.REG_SZ")
     hkey = hkey_w(w_hkey, space)
-    if space.is_w(w_subkey, space.w_None):
-        subkey = None
-    else:
-        subkey = space.text_w(w_subkey)
-    with rffi.scoped_str2charp(value) as dataptr:
-        ret = rwinreg.RegSetValue(hkey, subkey, rwinreg.REG_SZ, dataptr, len(value))
-        if ret != 0:
-            raiseWindowsError(space, ret, 'RegSetValue')
+    with rffi.scoped_unicode2wcharp(space.unicode_w(w_subkey)) as subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, subkey)
+        with rffi.scoped_unicode2wcharp(value) as dataptr:
+            c_dataptr = rffi.cast(rffi.CCHARP, dataptr)
+            ret = rwinreg.RegSetValue(hkey, c_subkey, rwinreg.REG_SZ, 
+                                            c_dataptr, len(value))
+            if ret != 0:
+                raiseWindowsError(space, ret, 'RegSetValue')
 
 def QueryValue(space, w_hkey, w_subkey):
     """string = QueryValue(key, sub_key) - retrieves the unnamed value for a key.
@@ -239,30 +246,37 @@
     if space.is_w(w_subkey, space.w_None):
         subkey = None
     else:
-        subkey = space.text_w(w_subkey)
-    with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
-        ret = rwinreg.RegQueryValue(hkey, subkey, None, bufsize_p)
-        bufSize = intmask(bufsize_p[0])
-        if ret == rwinreg.ERROR_MORE_DATA:
-            bufSize = 256
-        elif ret != 0:
-            raiseWindowsError(space, ret, 'RegQueryValue')
+        subkey = space.unicode_w(w_subkey)
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        with lltype.scoped_alloc(rwin32.PLONG.TO, 1) as bufsize_p:
+            ret = rwinreg.RegQueryValue(hkey, c_subkey, None, bufsize_p)
+            bufSize = intmask(bufsize_p[0])
+            if ret == rwinreg.ERROR_MORE_DATA:
+                bufSize = 256
+            elif ret != 0:
+                raiseWindowsError(space, ret, 'RegQueryValue')
 
-        while True:
-            with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as buf:
-                ret = rwinreg.RegQueryValue(hkey, subkey, buf, bufsize_p)
-                if ret == rwinreg.ERROR_MORE_DATA:
-                    # Resize and retry
-                    bufSize *= 2
-                    bufsize_p[0] = bufSize
-                    continue
+            while True:
+                with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as buf:
+                    ret = rwinreg.RegQueryValue(hkey, c_subkey, buf, bufsize_p)
+                    if ret == rwinreg.ERROR_MORE_DATA:
+                        print 'bufSize was %d, too small' % bufSize
+                        # Resize and retry
+                        bufSize *= 2
+                        bufsize_p[0] = bufSize
+                        continue
 
-                if ret != 0:
-                    raiseWindowsError(space, ret, 'RegQueryValue')
-                length = intmask(bufsize_p[0] - 1)
-                return space.newtext(rffi.charp2strn(buf, length))
+                    if ret != 0:
+                        raiseWindowsError(space, ret, 'RegQueryValue')
+                    length = intmask(bufsize_p[0] - 1) / 2
+                    wide_buf = rffi.cast(rffi.CWCHARP, buf)
+                    return space.newunicode(rffi.wcharp2unicoden(wide_buf, length))
 
 def convert_to_regdata(space, w_value, typ):
+    '''
+    returns CCHARP, int
+    '''
     buf = None
 
     if typ == rwinreg.REG_DWORD:
@@ -282,11 +296,9 @@
             buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
             buf[0] = '\0'
         else:
-            if space.isinstance_w(w_value, space.w_unicode):
-                w_value = space.call_method(w_value, 'encode',
-                                            space.newtext('mbcs'))
-            buf = rffi.str2charp(space.text_w(w_value))
-            buflen = space.len_w(w_value) + 1
+            buf = rffi.unicode2wcharp(space.unicode_w(w_value))
+            buf = rffi.cast(rffi.CCHARP, buf)
+            buflen = (space.len_w(w_value) * 2) + 1
 
     elif typ == rwinreg.REG_MULTI_SZ:
         if space.is_w(w_value, space.w_None):
@@ -302,28 +314,29 @@
             while True:
                 try:
                     w_item = space.next(w_iter)
-                    if space.isinstance_w(w_item, space.w_unicode):
-                        w_item = space.call_method(w_item, 'encode',
-                                                   space.newtext('mbcs'))
-                    item = space.bytes_w(w_item)
+                    item = space.unicode_w(w_item)
                     strings.append(item)
-                    buflen += len(item) + 1
+                    buflen += 2 * (len(item) + 1)
                 except OperationError as e:
                     if not e.match(space, space.w_StopIteration):
                         raise       # re-raise other app-level exceptions
                     break
-            buflen += 1
+            buflen += 2
             buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
 
             # Now copy data
             buflen = 0
             for string in strings:
-                for i in range(len(string)):
-                    buf[buflen + i] = string[i]
-                buflen += len(string) + 1
+                with rffi.scoped_unicode2wcharp(string) as wchr:
+                    c_str = rffi.cast(rffi.CCHARP, wchr)
+                    for i in range(len(string) * 2):
+                        buf[buflen + i] = c_str[i]
+                buflen += (len(string) + 1) * 2
                 buf[buflen - 1] = '\0'
-            buflen += 1
+                buf[buflen - 2] = '\0'
+            buflen += 2
             buf[buflen - 1] = '\0'
+            buf[buflen - 2] = '\0'
 
     else: # REG_BINARY and ALL unknown data types.
         if space.is_w(w_value, space.w_None):
@@ -357,37 +370,40 @@
 
     elif typ == rwinreg.REG_SZ or typ == rwinreg.REG_EXPAND_SZ:
         if not buflen:
-            s = ""
+            s = u""
         else:
             # may or may not have a trailing NULL in the buffer.
-            buf = rffi.cast(rffi.CCHARP, buf)
+            buf = rffi.cast(rffi.CWCHARP, buf)
+            buflen /= 2
             if buf[buflen - 1] == '\x00':
                 buflen -= 1
-            s = rffi.charp2strn(buf, buflen)
-        w_s = space.newbytes(s)
-        return space.call_method(w_s, 'decode', space.newtext('mbcs'))
+            s = rffi.wcharp2unicoden(buf, buflen)
+        w_s = space.newunicode(s)
+        return w_s
 
     elif typ == rwinreg.REG_MULTI_SZ:
         if not buflen:
             return space.newlist([])
+        buf = rffi.cast(rffi.CWCHARP, buf)
+        buflen /= 2
         i = 0
         l = []
         while i < buflen and buf[i]:
             s = []
-            while i < buflen and buf[i] != '\0':
+            while i < buflen and buf[i] != u'\0':
                 s.append(buf[i])
                 i += 1
             if len(s) == 0:
                 break
-            s = ''.join(s)
-            l.append(space.newtext(s))
+            s = u''.join(s)
+            l.append(space.newunicode(s))
             i += 1
         return space.newlist(l)
 
     else: # REG_BINARY and all other types
         return space.newbytes(rffi.charpsize2str(buf, buflen))
 
- at unwrap_spec(value_name="text", typ=int)
+ at unwrap_spec(value_name="unicode", typ=int)
 def SetValueEx(space, w_hkey, value_name, w_reserved, typ, w_value):
     """SetValueEx(key, value_name, reserved, type, value) - Stores data in the value field of an open registry key.
 
@@ -422,7 +438,9 @@
     hkey = hkey_w(w_hkey, space)
     buf, buflen = convert_to_regdata(space, w_value, typ)
     try:
-        ret = rwinreg.RegSetValueEx(hkey, value_name, 0, typ, buf, buflen)
+        with rffi.scoped_unicode2wcharp(value_name) as wide_vn:
+            c_vn = rffi.cast(rffi.CCHARP, wide_vn)
+            ret = rwinreg.RegSetValueEx(hkey, c_vn, 0, typ, buf, buflen)
     finally:
         lltype.free(buf, flavor='raw')
     if ret != 0:
@@ -437,38 +455,40 @@
     if space.is_w(w_subkey, space.w_None):
         subkey = None
     else:
-        subkey = space.text_w(w_subkey)
+        subkey = space.unicode_w(w_subkey)
     null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
-    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
-        ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword, null_dword,
-                                      None, retDataSize)
-        bufSize = intmask(retDataSize[0])
-        if ret == rwinreg.ERROR_MORE_DATA:
-            bufSize = 256
-        elif ret != 0:
-            raiseWindowsError(space, ret, 'RegQueryValueEx')
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize:
+            ret = rwinreg.RegQueryValueEx(hkey, c_subkey, null_dword, null_dword,
+                                          None, retDataSize)
+            bufSize = intmask(retDataSize[0])
+            if ret == rwinreg.ERROR_MORE_DATA:
+                bufSize = 256
+            elif ret != 0:
+                raiseWindowsError(space, ret, 'RegQueryValueEx')
 
-        while True:
-            with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as databuf:
-                with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
+            while True:
+                with lltype.scoped_alloc(rffi.CCHARP.TO, bufSize) as databuf:
+                    with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType:
 
-                    ret = rwinreg.RegQueryValueEx(hkey, subkey, null_dword,
-                                                  retType, databuf, retDataSize)
-                    if ret == rwinreg.ERROR_MORE_DATA:
-                        # Resize and retry
-                        bufSize *= 2
-                        retDataSize[0] = rffi.cast(rwin32.DWORD, bufSize)
-                        continue
-                    if ret != 0:
-                        raiseWindowsError(space, ret, 'RegQueryValueEx')
-                    length = intmask(retDataSize[0])
-                    return space.newtuple([
-                        convert_from_regdata(space, databuf,
-                                             length, retType[0]),
-                        space.newint(intmask(retType[0])),
+                        ret = rwinreg.RegQueryValueEx(hkey, c_subkey, null_dword,
+                                                      retType, databuf, retDataSize)
+                        if ret == rwinreg.ERROR_MORE_DATA:
+                            # Resize and retry
+                            bufSize *= 2
+                            retDataSize[0] = rffi.cast(rwin32.DWORD, bufSize)
+                            continue
+                        if ret != 0:
+                            raiseWindowsError(space, ret, 'RegQueryValueEx')
+                        length = intmask(retDataSize[0])
+                        return space.newtuple([
+                            convert_from_regdata(space, databuf,
+                                                 length, retType[0]),
+                            space.newint(intmask(retType[0])),
                         ])
 
- at unwrap_spec(subkey="text")
+ at unwrap_spec(subkey="unicode")
 def CreateKey(space, w_hkey, subkey):
     """key = CreateKey(key, sub_key) - Creates or opens the specified key.
 
@@ -482,13 +502,15 @@
 The return value is the handle of the opened key.
 If the function fails, an exception is raised."""
     hkey = hkey_w(w_hkey, space)
-    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-        ret = rwinreg.RegCreateKey(hkey, subkey, rethkey)
-        if ret != 0:
-            raiseWindowsError(space, ret, 'CreateKey')
-        return W_HKEY(space, rethkey[0])
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
+            ret = rwinreg.RegCreateKey(hkey, c_subkey, rethkey)
+            if ret != 0:
+                raiseWindowsError(space, ret, 'CreateKey')
+            return W_HKEY(space, rethkey[0])
 
- at unwrap_spec(sub_key="text", reserved=int, access=rffi.r_uint)
+ at unwrap_spec(sub_key="unicode", reserved=int, access=rffi.r_uint)
 def CreateKeyEx(space, w_key, sub_key, reserved=0, access=rwinreg.KEY_WRITE):
     """key = CreateKey(key, sub_key) - Creates or opens the specified key.
 
@@ -502,17 +524,19 @@
 The return value is the handle of the opened key.
 If the function fails, an exception is raised."""
     hkey = hkey_w(w_key, space)
-    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-        ret = rwinreg.RegCreateKeyEx(hkey, sub_key, reserved, None, 0,
-                                     access, None, rethkey,
-                                     lltype.nullptr(rwin32.LPDWORD.TO))
-        if ret != 0:
-            raiseWindowsError(space, ret, 'CreateKeyEx')
-        return W_HKEY(space, rethkey[0])
+    with rffi.scoped_unicode2wcharp(sub_key) as wide_sub_key:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_sub_key)
+        with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
+            ret = rwinreg.RegCreateKeyEx(hkey, c_subkey, reserved, None, 0,
+                                         access, None, rethkey,
+                                         lltype.nullptr(rwin32.LPDWORD.TO))
+            if ret != 0:
+                raiseWindowsError(space, ret, 'CreateKeyEx')
+            return W_HKEY(space, rethkey[0])
 
- at unwrap_spec(subkey="text")
+ at unwrap_spec(subkey="unicode")
 def DeleteKey(space, w_hkey, subkey):
-    """DeleteKey(key, sub_key) - Deletes the specified key.
+    """DeleteKey(key, subkey) - Deletes the specified key.
 
 key is an already open key, or any one of the predefined HKEY_* constants.
 sub_key is a string that must be a subkey of the key identified by the key parameter.
@@ -523,22 +547,26 @@
 If the method succeeds, the entire key, including all of its values,
 is removed.  If the method fails, an EnvironmentError exception is raised."""
     hkey = hkey_w(w_hkey, space)
-    ret = rwinreg.RegDeleteKey(hkey, subkey)
-    if ret != 0:
-        raiseWindowsError(space, ret, 'RegDeleteKey')
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        ret = rwinreg.RegDeleteKey(hkey, c_subkey)
+        if ret != 0:
+            raiseWindowsError(space, ret, 'RegDeleteKey')
 
- at unwrap_spec(subkey="text")
+ at unwrap_spec(subkey="unicode")
 def DeleteValue(space, w_hkey, subkey):
     """DeleteValue(key, value) - Removes a named value from a registry key.
 
 key is an already open key, or any one of the predefined HKEY_* constants.
 value is a string that identifies the value to remove."""
     hkey = hkey_w(w_hkey, space)
-    ret = rwinreg.RegDeleteValue(hkey, subkey)
-    if ret != 0:
-        raiseWindowsError(space, ret, 'RegDeleteValue')
+    with rffi.scoped_unicode2wcharp(subkey) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        ret = rwinreg.RegDeleteValue(hkey, c_subkey)
+        if ret != 0:
+            raiseWindowsError(space, ret, 'RegDeleteValue')
 
- at unwrap_spec(sub_key="text", reserved=int, access=rffi.r_uint)
+ at unwrap_spec(sub_key="unicode", reserved=int, access=rffi.r_uint)
 def OpenKey(space, w_key, sub_key, reserved=0, access=rwinreg.KEY_READ):
     """key = OpenKey(key, sub_key, res = 0, sam = KEY_READ) - Opens the specified key.
 
@@ -551,11 +579,13 @@
 The result is a new handle to the specified key
 If the function fails, an EnvironmentError exception is raised."""
     hkey = hkey_w(w_key, space)
-    with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
-        ret = rwinreg.RegOpenKeyEx(hkey, sub_key, reserved, access, rethkey)
-        if ret != 0:
-            raiseWindowsError(space, ret, 'RegOpenKeyEx')
-        return W_HKEY(space, rethkey[0])
+    with rffi.scoped_unicode2wcharp(sub_key) as wide_subkey:
+        c_subkey = rffi.cast(rffi.CCHARP, wide_subkey)
+        with lltype.scoped_alloc(rwinreg.PHKEY.TO, 1) as rethkey:
+            ret = rwinreg.RegOpenKeyEx(hkey, c_subkey, reserved, access, rethkey)
+            if ret != 0:
+                raiseWindowsError(space, ret, 'RegOpenKeyEx')
+            return W_HKEY(space, rethkey[0])
 
 @unwrap_spec(index=int)
 def EnumValue(space, w_hkey, index):
@@ -590,15 +620,16 @@
             bufDataSize = intmask(retDataSize[0])
             bufValueSize = intmask(retValueSize[0])
 
-            with lltype.scoped_alloc(rffi.CCHARP.TO,
+            with lltype.scoped_alloc(rffi.CWCHARP.TO,
                                      intmask(retValueSize[0])) as valuebuf:
                 while True:
                     with lltype.scoped_alloc(rffi.CCHARP.TO,
                                              bufDataSize) as databuf:
                         with lltype.scoped_alloc(rwin32.LPDWORD.TO,
                                                  1) as retType:
+                            c_valuebuf = rffi.cast(rffi.CCHARP, valuebuf)
                             ret = rwinreg.RegEnumValue(
-                                hkey, index, valuebuf, retValueSize,
+                                hkey, index, c_valuebuf, retValueSize,
                                 null_dword, retType, databuf, retDataSize)
                             if ret == rwinreg.ERROR_MORE_DATA:
                                 # Resize and retry
@@ -614,7 +645,7 @@
 
                             length = intmask(retDataSize[0])
                             return space.newtuple([
-                                space.newtext(rffi.charp2str(valuebuf)),
+                                space.newunicode(rffi.wcharp2unicode(valuebuf)),
                                 convert_from_regdata(space, databuf,
                                                      length, retType[0]),
                                 space.newint(intmask(retType[0])),
@@ -647,7 +678,7 @@
                                        lltype.nullptr(rwin32.PFILETIME.TO))
             if ret != 0:
                 raiseWindowsError(space, ret, 'RegEnumKeyEx')
-            return space.newtext(rffi.charp2str(buf))
+            return space.newunicode(rffi.wcharp2unicode(rffi.cast(rffi.CWCHARP, buf)))
 
 def QueryInfoKey(space, w_hkey):
     """tuple = QueryInfoKey(key) - Returns information about a key.
@@ -726,7 +757,7 @@
     raise oefmt(space.w_NotImplementedError,
                 "not implemented on this platform")
 
- at unwrap_spec(sub_key="text", reserved=int, access=rffi.r_uint)
+ at unwrap_spec(sub_key="unicode", reserved=int, access=rffi.r_uint)
 def DeleteKeyEx(space, w_key, sub_key, reserved=0, access=rwinreg.KEY_WOW64_64KEY):
     """DeleteKeyEx(key, sub_key, sam, res) - Deletes the specified key.
 
diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py
--- a/pypy/module/_winreg/test/test_winreg.py
+++ b/pypy/module/_winreg/test/test_winreg.py
@@ -19,7 +19,7 @@
     canSaveKey = len(ret) > 0
 
 class AppTestHKey:
-    #spaceconfig = dict(usemodules=('_winreg',))
+    spaceconfig = dict(usemodules=('_winreg',))
 
     def test_repr(self):
         import winreg
@@ -27,12 +27,12 @@
         assert str(k) == "<PyHKEY:0x123>"
 
 class AppTestFfi:
-    #spaceconfig = dict(usemodules=('_winreg',))
+    spaceconfig = dict(usemodules=('_winreg',))
 
     def setup_class(cls):
-        import _winreg
+        import _winreg as winreg
         space = cls.space
-        cls.root_key = _winreg.HKEY_CURRENT_USER
+        cls.root_key = winreg.HKEY_CURRENT_USER
         cls.test_key_name = "SOFTWARE\\Pypy Registry Test Key - Delete Me"
         cls.w_root_key = space.wrap(cls.root_key)
         cls.w_test_key_name = space.wrap(cls.test_key_name)
@@ -40,22 +40,22 @@
         cls.w_tmpfilename = space.wrap(str(udir.join('winreg-temp')))
 
         test_data = [
-            ("Int Value", 0xFEDCBA98, _winreg.REG_DWORD),
-            ("Str Value", "A string Value", _winreg.REG_SZ),
-            ("Unicode Value", u"A unicode Value", _winreg.REG_SZ),
-            ("Str Expand", "The path is %path%", _winreg.REG_EXPAND_SZ),
-            ("Multi Str", ["Several", "string", u"values"], _winreg.REG_MULTI_SZ),
+            ("Int Value", 0xFEDCBA98, winreg.REG_DWORD),
+            ("Str Value", b"A string Value", winreg.REG_SZ),
+            ("Unicode Value", "A unicode Value", winreg.REG_SZ),
+            ("Str Expand", "The path is %path%", winreg.REG_EXPAND_SZ),
+            ("Multi Str", [b"Several", u"string", u"values"], winreg.REG_MULTI_SZ),
             ]
         cls.w_test_data = w_test_data = space.wrap(test_data)
         w_btest = space.newtuple([space.wrap("Raw data"),
                                   space.newbytes("binary\x00data"),
-                                  space.wrap(_winreg.REG_BINARY)])
+                                  space.wrap(winreg.REG_BINARY)])
         w_test_data.append(w_btest)
 
     def teardown_class(cls):
-        import winreg
+        import _winreg
         try:
-            winreg.DeleteKey(cls.root_key, cls.test_key_name)
+            _winreg.DeleteKey(cls.root_key, cls.test_key_name)
         except WindowsError:
             pass
 
@@ -67,14 +67,14 @@
 
     def test_simple_write(self):
         from winreg import SetValue, QueryValue, REG_SZ
-        value = "Some Default value"
+        value = u"Some Default value"
         SetValue(self.root_key, self.test_key_name, REG_SZ, value)
         assert QueryValue(self.root_key, self.test_key_name) == value
 
     def test_CreateKey(self):
         from winreg import CreateKey, QueryInfoKey
         key = CreateKey(self.root_key, self.test_key_name)
-        sub_key = CreateKey(key, "sub_key")
+        sub_key = CreateKey(key, u"sub_key")
 
         nkeys, nvalues, since_mod = QueryInfoKey(key)
         assert nkeys == 1
@@ -86,7 +86,7 @@
         from winreg import CreateKeyEx, QueryInfoKey
         from winreg import KEY_ALL_ACCESS, KEY_READ
         key = CreateKeyEx(self.root_key, self.test_key_name, 0, KEY_ALL_ACCESS)
-        sub_key = CreateKeyEx(key, "sub_key", 0, KEY_READ)
+        sub_key = CreateKeyEx(key, u"sub_key", 0, KEY_READ)
 
         nkeys, nvalues, since_mod = QueryInfoKey(key)
         assert nkeys == 1
@@ -97,7 +97,7 @@
     def test_close(self):
         from winreg import OpenKey, CloseKey, FlushKey, QueryInfoKey
         key = OpenKey(self.root_key, self.test_key_name)
-        sub_key = OpenKey(key, "sub_key")
+        sub_key = OpenKey(key, u"sub_key")
 
         int_sub_key = int(sub_key)
         FlushKey(sub_key)
@@ -119,7 +119,7 @@
     def test_with(self):
         from winreg import OpenKey
         with OpenKey(self.root_key, self.test_key_name) as key:
-            with OpenKey(key, "sub_key") as sub_key:
+            with OpenKey(key, u"sub_key") as sub_key:
                 assert key.handle != 0
                 assert sub_key.handle != 0
         assert key.handle == 0
@@ -140,17 +140,17 @@
             assert 0, "Did not raise"
 
     def test_SetValueEx(self):
+        # this test leaves open keys. If it fails, others will too
         from winreg import CreateKey, SetValueEx, REG_BINARY, REG_DWORD
         key = CreateKey(self.root_key, self.test_key_name)
-        sub_key = CreateKey(key, "sub_key")
+        sub_key = CreateKey(key, u"sub_key")
         SetValueEx(sub_key, 'Int Value', 0, REG_DWORD, None)
         SetValueEx(sub_key, 'Int Value', 0, REG_DWORD, 45)
         for name, value, type in self.test_data:
             SetValueEx(sub_key, name, 0, type, value)
-        exc = raises(TypeError, SetValueEx, sub_key, 'test_name', None,
-                                            REG_BINARY, memoryview('abc'))
-        assert str(exc.value) == ("Objects of type 'memoryview' can not "
-                                  "be used as binary registry values")
+        # cannot wrap a memoryview in setup_class for test_data
+        SetValueEx(sub_key, u'test_name', None,
+                            REG_BINARY, memoryview(b'abc'))
 
     def test_readValues(self):
         from winreg import OpenKey, EnumValue, QueryValueEx, EnumKey
@@ -163,27 +163,31 @@
                 data = EnumValue(sub_key, index)
             except EnvironmentError as e:
                 break
-            assert data in self.test_data
+            if data[0] != 'test_name':
+                # cannot wrap a memoryview in setup_class for test_data
+                assert data in self.test_data
             index = index + 1
-        assert index == len(self.test_data)
+        assert index == len(self.test_data) + 1
 
         for name, value, type in self.test_data:
             result = QueryValueEx(sub_key, name)
             assert result == (value, type)
             if type == REG_SZ or type == REG_EXPAND_SZ:
-                assert isinstance(result[0], unicode)     # not string
+                assert not isinstance(result[0], bytes)
 
         assert EnumKey(key, 0) == "sub_key"
         raises(EnvironmentError, EnumKey, key, 1)
 
     def test_delete(self):
         # must be run after test_SetValueEx
-        from _winreg import OpenKey, KEY_ALL_ACCESS, DeleteValue, DeleteKey
+        from winreg import OpenKey, KEY_ALL_ACCESS, DeleteValue, DeleteKey
         key = OpenKey(self.root_key, self.test_key_name, 0, KEY_ALL_ACCESS)
         sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
 
         for name, value, type in self.test_data:
             DeleteValue(sub_key, name)
+        # cannot wrap a memoryview in setup_class for test_data
+        DeleteValue(sub_key, 'test_name')
 
         DeleteKey(key, "sub_key")
 
@@ -242,7 +246,7 @@
                 skip("access denied to registry key "
                      "(are you running in a non-interactive session?)")
             raise
-        QueryValueEx(HKEY_PERFORMANCE_DATA, None)
+        QueryValueEx(HKEY_PERFORMANCE_DATA, 'Global')
 
     def test_reflection_unsupported(self):
         import sys
diff --git a/rpython/rlib/rwinreg.py b/rpython/rlib/rwinreg.py
--- a/rpython/rlib/rwinreg.py
+++ b/rpython/rlib/rwinreg.py
@@ -47,7 +47,7 @@
 HKEY = rwin32.HANDLE
 PHKEY = rffi.CArrayPtr(HKEY)
 REGSAM = rwin32.DWORD
-suffix = 'A'
+suffix = 'W'
 
 RegSetValue = external(
     'RegSetValue' + suffix,


More information about the pypy-commit mailing list