Commits

Amaury Forgeot d'Arc committed 667476c Merge

Merge default

  • Participants
  • Parent commits 415545b, 1b88f6a
  • Branches shorter-float-repr

Comments (0)

Files changed (7)

File pypy/module/posix/__init__.py

         interpleveldefs['nice'] = 'interp_posix.nice'
 
     for name in ['setsid', 'getuid', 'geteuid', 'getgid', 'getegid', 'setuid',
-                 'seteuid', 'setgid', 'setegid', 'getpgrp', 'setpgrp',
-                 'getppid', 'getpgid', 'setpgid', 'setreuid', 'setregid',
-                 'getsid', 'setsid']:
+                 'seteuid', 'setgid', 'setegid', 'getgroups', 'getpgrp', 
+                 'setpgrp', 'getppid', 'getpgid', 'setpgid', 'setreuid', 
+                 'setregid', 'getsid', 'setsid']:
         if hasattr(os, name):
             interpleveldefs[name] = 'interp_posix.%s' % (name,)
     # not visible via os, inconsistency in nt:

File pypy/module/posix/interp_posix.py

     return space.wrap(os.geteuid())
 geteuid.unwrap_spec = [ObjSpace]
 
+def getgroups(space):
+    """ getgroups() -> list of group IDs
+
+    Return list of supplemental group IDs for the process.
+    """
+    return space.newlist([space.wrap(e) for e in os.getgroups()])
+getgroups.unwrap_spec = [ObjSpace]
+
 def getpgrp(space):
     """ getpgrp() -> pgrp
 

File pypy/module/posix/test/test_posix2.py

             cls.w_geteuid = space.wrap(os.geteuid())
         if hasattr(os, 'getgid'):
             cls.w_getgid = space.wrap(os.getgid())
+        if hasattr(os, 'getgroups'):
+            cls.w_getgroups = space.newlist([space.wrap(e) for e in os.getgroups()])
         if hasattr(os, 'getpgid'):
             cls.w_getpgid = space.wrap(os.getpgid(os.getpid()))
         if hasattr(os, 'getsid'):
         def test_os_getgid(self):
             os = self.posix
             assert os.getgid() == self.getgid
+            
+    if hasattr(os, 'getgroups'):
+        def test_os_getgroups(self):
+            os = self.posix
+            assert os.getgroups() == self.getgroups
 
     if hasattr(os, 'getpgid'):
         def test_os_getpgid(self):

File pypy/module/unicodedata/interp_ucd.py

 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.rlib.rarithmetic import r_longlong
+from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.runicode import MAXUNICODE
+import sys
 
 from pypy.module.unicodedata import unicodedb_5_2_0, unicodedb_3_2_0
 
 NCount = (VCount*TCount)
 SCount = (LCount*NCount)
 
-def unichr_to_code_w(space, w_unichr):
-    if not space.is_true(space.isinstance(w_unichr, space.w_unicode)):
-        raise OperationError(space.w_TypeError, space.wrap('argument 1 must be unicode'))
-    if not space.int_w(space.len(w_unichr)) == 1:
-        raise OperationError(space.w_TypeError, space.wrap('need a single Unicode character as parameter'))
-    return space.int_w(space.ord(w_unichr))
+# Since Python2.7, the unicodedata module gives a preview of Python3 character
+# handling: on narrow unicode builds, a surrogate pair is considered as one
+# unicode code point.
+
+# The functions below are subtly different from the ones in runicode.py.
+# When PyPy implements Python 3 they should be merged.
+
+def UNICHR(c):
+    if c <= sys.maxunicode and c <= MAXUNICODE:
+        return unichr(c)
+    else:
+        c -= 0x10000
+        return (unichr(0xD800 + (c >> 10)) +
+                unichr(0xDC00 + (c & 0x03FF)))
+
+def ORD(u):
+    assert isinstance(u, unicode)
+    if len(u) == 1:
+        return ord(u[0])
+    elif len(u) == 2:
+        ch1 = ord(u[0])
+        ch2 = ord(u[1])
+        if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF:
+            return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000
+    raise ValueError
+
+if MAXUNICODE > 0xFFFF:
+    # Target is wide build
+    def unichr_to_code_w(space, w_unichr):
+        if not space.is_true(space.isinstance(w_unichr, space.w_unicode)):
+            raise OperationError(space.w_TypeError, space.wrap(
+                'argument 1 must be unicode'))
+
+        if not we_are_translated() and sys.maxunicode == 0xFFFF:
+            # Host CPython is narrow build, accept surrogates
+            try:
+                return ORD(space.unicode_w(w_unichr))
+            except ValueError:
+                raise OperationError(space.w_TypeError, space.wrap(
+                    'need a single Unicode character as parameter'))
+        else:
+            if not space.int_w(space.len(w_unichr)) == 1:
+                raise OperationError(space.w_TypeError, space.wrap(
+                    'need a single Unicode character as parameter'))
+            return space.int_w(space.ord(w_unichr))
+
+    def code_to_unichr(code):
+        if not we_are_translated() and sys.maxunicode == 0xFFFF:
+            # Host CPython is narrow build, generate surrogates
+            return UNICHR(code)
+        else:
+            return unichr(code)
+else:
+    # Target is narrow build
+    def unichr_to_code_w(space, w_unichr):
+        if not space.is_true(space.isinstance(w_unichr, space.w_unicode)):
+            raise OperationError(space.w_TypeError, space.wrap(
+                'argument 1 must be unicode'))
+
+        if not we_are_translated() and sys.maxunicode > 0xFFFF:
+            # Host CPython is wide build, forbid surrogates
+            if not space.int_w(space.len(w_unichr)) == 1:
+                raise OperationError(space.w_TypeError, space.wrap(
+                    'need a single Unicode character as parameter'))
+            return space.int_w(space.ord(w_unichr))
+
+        else:
+            # Accept surrogates
+            try:
+                return ORD(space.unicode_w(w_unichr))
+            except ValueError:
+                raise OperationError(space.w_TypeError, space.wrap(
+                    'need a single Unicode character as parameter'))
+
+    def code_to_unichr(code):
+        # generate surrogates for large codes
+        return UNICHR(code)
+
 
 class UCD(Wrappable):
     def __init__(self, unicodedb):
     _get_code.unwrap_spec = ['self', ObjSpace, str]
     
     def lookup(self, space, name):
-        w_code = self._get_code(space, name)
         try:
-            return space.call_function(space.builtin.get('unichr'), w_code)
-        except OperationError, ex:
-            if not ex.match(space, space.w_ValueError):
-                raise
-            msg = space.mod(space.wrap("result %d larger than sys.maxunicode"), w_code)
+            code = self._lookup(name.upper())
+        except KeyError:
+            msg = space.mod(space.wrap("undefined character name '%s'"), space.wrap(name))
             raise OperationError(space.w_KeyError, msg)
-
+        return space.wrap(code_to_unichr(code))
     lookup.unwrap_spec = ['self', ObjSpace, str]
 
     def name(self, space, w_unichr, w_default=NoneNotWrapped):
 
     def mirrored(self, space, w_unichr):
         code = unichr_to_code_w(space, w_unichr)
-        return space.wrap(self._mirrored(code))
+        # For no reason, unicodedata.mirrored() returns an int, not a bool
+        return space.wrap(int(self._mirrored(code)))
     mirrored.unwrap_spec = ['self', ObjSpace, W_Root]
 
     def decomposition(self, space, w_unichr):

File pypy/module/unicodedata/test/test_unicodedata.py

 from py.test import raises, skip
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
 from pypy.conftest import gettestobjspace
 
 from pypy.module.unicodedata import unicodedb_3_2_0, unicodedb_5_2_0
 
     def test_cjk(self):
         import sys
-        if sys.maxunicode < 0x10ffff:
-            skip("requires a 'wide' python build.")
         import unicodedata
         cases = ((0x3400, 0x4DB5),
                  (0x4E00, 0x9FA5))
             # Test at and inside the boundary
             for i in (first, first + 1, last - 1, last):
                 charname = 'CJK UNIFIED IDEOGRAPH-%X'%i
-                assert unicodedata.name(unichr(i)) == charname
-                assert unicodedata.lookup(charname) == unichr(i)
+                char = ('\\U%08X' % i).decode('unicode-escape')
+                assert unicodedata.name(char) == charname
+                assert unicodedata.lookup(charname) == char
             # Test outside the boundary
             for i in first - 1, last + 1:
                 charname = 'CJK UNIFIED IDEOGRAPH-%X'%i
+                char = ('\\U%08X' % i).decode('unicode-escape')
                 try:
-                    unicodedata.name(unichr(i))
-                except ValueError:
-                    pass
+                    unicodedata.name(char)
+                except ValueError, e:
+                    assert e.message == 'no such name'
                 raises(KeyError, unicodedata.lookup, charname)
 
     def test_bug_1704793(self): # from CPython
-        import sys, unicodedata
-        if sys.maxunicode == 65535:
-            raises(KeyError, unicodedata.lookup, "GOTHIC LETTER FAIHU")
+        import unicodedata
+        assert unicodedata.lookup("GOTHIC LETTER FAIHU") == u'\U00010346'
 
     def test_normalize(self):
         import unicodedata
                 else:
                     assert len(lines) == 1
 
+    def test_mirrored(self):
+        import unicodedata
+        # For no reason, unicodedata.mirrored() returns an int, not a bool
+        assert repr(unicodedata.mirrored(u' ')) == '0'
+
 class TestUnicodeData(object):
     def setup_class(cls):
         import random, unicodedata
         raises(KeyError, unicodedb_3_2_0.lookup, 'BENZENE RING WITH CIRCLE')
         raises(KeyError, unicodedb_3_2_0.name, 9187)
 
+class TestTranslated(BaseRtypingTest, LLRtypeMixin):
 
+    def test_translated(self):
+        def f(n):
+            if n == 0:
+                return -1
+            else:
+                u = unicodedb_5_2_0.lookup("GOTHIC LETTER FAIHU")
+                return u
+        res = self.interpret(f, [1])
+        print hex(res)
+        assert res == f(1)
 
+    def test_code_to_unichr(self):
+        from pypy.module.unicodedata.interp_ucd import code_to_unichr
+        res = self.ll_to_unicode(self.interpret(code_to_unichr, [0x10346]))
+        assert res == u'\U00010346'
+
+
+

File pypy/rpython/module/ll_os.py

                            ('tms_stime', rffi.INT),
                            ('tms_cutime', rffi.INT),
                            ('tms_cstime', rffi.INT)])
+        
+        GID_T = platform.SimpleType('gid_t',rffi.INT) 
+        #TODO right now is used only in getgroups, may need to update other functions like setgid
+                           
 
     SEEK_SET = platform.DefinedConstantInteger('SEEK_SET')
     SEEK_CUR = platform.DefinedConstantInteger('SEEK_CUR')
     @registering_if(os, 'getegid')
     def register_os_getegid(self):
         return self.extdef_for_os_function_returning_int('getegid')
+        
+    @registering_if(os, 'getgroups')
+    def register_os_getgroups(self):
+        GP = rffi.CArrayPtr(self.GID_T)
+        c_getgroups = self.llexternal('getgroups',[rffi.INT, GP],rffi.INT)
+
+        def getgroups_llimpl():
+            groups = lltype.malloc(GP.TO, 0, flavor='raw')
+            try:
+                n = c_getgroups(0, groups)
+                if n >= 0:
+                    lltype.free(groups, flavor='raw')
+                    groups = lltype.malloc(GP.TO, n, flavor='raw')
+                    n = c_getgroups(n,groups)
+                    result = [groups[i] for i in range(n)]
+                    if n >= 0:
+                        return result
+                raise OSError(rposix.get_errno(), "os_getgroups failed")
+            finally:
+                lltype.free(groups, flavor='raw')
+
+        return extdef([],[self.GID_T],llimpl=getgroups_llimpl, export_name="ll_os.ll_getgroups")
 
     @registering_if(os, 'getpgrp')
     def register_os_getpgrp(self):

File pypy/rpython/module/test/test_posix.py

                 return os.getgid()
             assert self.interpret(f, []) == f()
 
-
     if hasattr(os, 'setuid'):
         def test_os_setuid(self):
             def f():
                 assert res == fun(value)        
 
 class TestLLtype(BaseTestPosix, LLRtypeMixin):
-    pass
+
+    if hasattr(os, 'getgroups'):
+        def test_getgroups(self):
+            def f():
+                return os.getgroups()
+            ll_a = self.interpret(f, [])
+            assert self.ll_to_list(ll_a) == f()
 
 class TestOOtype(BaseTestPosix, OORtypeMixin):
     def test_fstat(self):