Author: Alex Gaynor <alex.gay...@gmail.com>
Branch: release-2.1.x
Changeset: r65613:a52810f16fa8
Date: 2013-07-24 08:49 -0700
http://bitbucket.org/pypy/pypy/changeset/a52810f16fa8/

Log:    Manually transplanted add-statvfs from default.

diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -275,7 +275,7 @@
         try:
             result.f_bfree = 1
             self.fail("No exception thrown")
-        except TypeError:
+        except (TypeError, AttributeError):
             pass
 
         try:
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -17,12 +17,13 @@
     'setregid', 'setreuid', 'setsid', 'setuid', 'stat_float_times', 'statvfs',
     'statvfs_result', 'symlink', 'sysconf', 'sysconf_names', 'tcgetpgrp', 
'tcsetpgrp',
     'ttyname', 'uname', 'wait', 'wait3', 'wait4'
-    ]
+]
 
 # the Win32 urandom implementation isn't going to translate on JVM or CLI so
 # we have to remove it
 lltype_only_defs.append('urandom')
 
+
 class Module(MixedModule):
     """This module provides access to operating system functionality that is
 standardized by the C Standard and the POSIX standard (a thinly
@@ -53,44 +54,49 @@
         appleveldefs['wait3'] = 'app_posix.wait3'
     if hasattr(os, 'wait4'):
         appleveldefs['wait4'] = 'app_posix.wait4'
-        
+
     interpleveldefs = {
-    'open'      : 'interp_posix.open',
-    'lseek'     : 'interp_posix.lseek',
-    'write'     : 'interp_posix.write',
-    'isatty'    : 'interp_posix.isatty',
-    'read'      : 'interp_posix.read',
-    'close'     : 'interp_posix.close',
-    'closerange': 'interp_posix.closerange',
-    'fstat'     : 'interp_posix.fstat',
-    'stat'      : 'interp_posix.stat',
-    'lstat'     : 'interp_posix.lstat',
-    'stat_float_times' : 'interp_posix.stat_float_times',
-    'dup'       : 'interp_posix.dup',
-    'dup2'      : 'interp_posix.dup2',
-    'access'    : 'interp_posix.access',
-    'times'     : 'interp_posix.times',
-    'system'    : 'interp_posix.system',
-    'unlink'    : 'interp_posix.unlink',
-    'remove'    : 'interp_posix.remove',
-    'getcwd'    : 'interp_posix.getcwd',
-    'getcwdu'   : 'interp_posix.getcwdu',
-    'chdir'     : 'interp_posix.chdir',
-    'mkdir'     : 'interp_posix.mkdir',
-    'rmdir'     : 'interp_posix.rmdir',
-    'environ'   : 'interp_posix.get(space).w_environ',
-    'listdir'   : 'interp_posix.listdir',
-    'strerror'  : 'interp_posix.strerror',
-    'pipe'      : 'interp_posix.pipe',
-    'chmod'     : 'interp_posix.chmod',
-    'rename'    : 'interp_posix.rename',
-    'umask'     : 'interp_posix.umask',
-    '_exit'     : 'interp_posix._exit',
-    'utime'     : 'interp_posix.utime',
-    '_statfields': 'interp_posix.getstatfields(space)',
-    'kill'      : 'interp_posix.kill',
-    'abort'     : 'interp_posix.abort',
-    'urandom'   : 'interp_posix.urandom',
+        'open': 'interp_posix.open',
+        'lseek': 'interp_posix.lseek',
+        'write': 'interp_posix.write',
+        'isatty': 'interp_posix.isatty',
+        'read': 'interp_posix.read',
+        'close': 'interp_posix.close',
+        'closerange': 'interp_posix.closerange',
+
+        'fstat': 'interp_posix.fstat',
+        'stat': 'interp_posix.stat',
+        'lstat': 'interp_posix.lstat',
+        'stat_float_times': 'interp_posix.stat_float_times',
+
+        'fstatvfs': 'interp_posix.fstatvfs',
+        'statvfs': 'interp_posix.statvfs',
+
+        'dup': 'interp_posix.dup',
+        'dup2': 'interp_posix.dup2',
+        'access': 'interp_posix.access',
+        'times': 'interp_posix.times',
+        'system': 'interp_posix.system',
+        'unlink': 'interp_posix.unlink',
+        'remove': 'interp_posix.remove',
+        'getcwd': 'interp_posix.getcwd',
+        'getcwdu': 'interp_posix.getcwdu',
+        'chdir': 'interp_posix.chdir',
+        'mkdir': 'interp_posix.mkdir',
+        'rmdir': 'interp_posix.rmdir',
+        'environ': 'interp_posix.get(space).w_environ',
+        'listdir': 'interp_posix.listdir',
+        'strerror': 'interp_posix.strerror',
+        'pipe': 'interp_posix.pipe',
+        'chmod': 'interp_posix.chmod',
+        'rename': 'interp_posix.rename',
+        'umask': 'interp_posix.umask',
+        '_exit': 'interp_posix._exit',
+        'utime': 'interp_posix.utime',
+        '_statfields': 'interp_posix.getstatfields(space)',
+        'kill': 'interp_posix.kill',
+        'abort': 'interp_posix.abort',
+        'urandom': 'interp_posix.urandom',
     }
 
     if hasattr(os, 'chown'):
@@ -167,8 +173,8 @@
         interpleveldefs['getlogin'] = 'interp_posix.getlogin'
 
     for name in ['setsid', 'getuid', 'geteuid', 'getgid', 'getegid', 'setuid',
-                 'seteuid', 'setgid', 'setegid', 'getgroups', 'getpgrp', 
-                 'setpgrp', 'getppid', 'getpgid', 'setpgid', 'setreuid', 
+                 'seteuid', 'setgid', 'setegid', 'getgroups', 'getpgrp',
+                 'setpgrp', 'getppid', 'getpgid', 'setpgid', 'setreuid',
                  'setregid', 'getsid', 'setsid']:
         if hasattr(os, name):
             interpleveldefs[name] = 'interp_posix.%s' % (name,)
@@ -177,7 +183,7 @@
         interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname'
     if hasattr(os, 'chroot'):
         interpleveldefs['chroot'] = 'interp_posix.chroot'
-    
+
     for name in RegisterOs.w_star:
         if hasattr(os, name):
             interpleveldefs[name] = 'interp_posix.' + name
@@ -186,7 +192,7 @@
         # if it's an ootype translation, remove all the defs that are lltype
         # only
         backend = space.config.translation.backend
-        if backend == 'cli' or backend == 'jvm':
+        if backend == 'cli' or backend == 'jvm' :
             for name in lltype_only_defs:
                 self.interpleveldefs.pop(name, None)
         MixedModule.__init__(self, space, w_name)
@@ -194,7 +200,7 @@
     def startup(self, space):
         from pypy.module.posix import interp_posix
         interp_posix.get(space).startup(space)
-        
+
 for constant in dir(os):
     value = getattr(os, constant)
     if constant.isupper() and type(value) is int:
diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -1,15 +1,17 @@
-from pypy.interpreter.gateway import unwrap_spec
+import os
+import sys
+
 from rpython.rlib import rposix, objectmodel, rurandom
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rarithmetic import r_longlong
 from rpython.rlib.unroll import unrolling_iterable
+from rpython.rtyper.module import ll_os_stat
+from rpython.rtyper.module.ll_os import RegisterOs
+
+from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
-from rpython.rtyper.module.ll_os import RegisterOs
-from rpython.rtyper.module import ll_os_stat
 from pypy.module.sys.interp_encoding import getfilesystemencoding
 
-import os
-import sys
 
 _WIN32 = sys.platform == 'win32'
 if _WIN32:
@@ -213,6 +215,7 @@
 STAT_FIELDS = unrolling_iterable(enumerate(ll_os_stat.STAT_FIELDS))
 PORTABLE_STAT_FIELDS = unrolling_iterable(
                                  enumerate(ll_os_stat.PORTABLE_STAT_FIELDS))
+STATVFS_FIELDS = unrolling_iterable(enumerate(ll_os_stat.STATVFS_FIELDS))
 
 def build_stat_result(space, st):
     if space.config.translation.type_system == 'ootype':
@@ -253,6 +256,16 @@
                                   space.wrap('stat_result'))
     return space.call_function(w_stat_result, w_tuple, w_keywords)
 
+
+def build_statvfs_result(space, st):
+    vals_w = [None] * len(ll_os_stat.STATVFS_FIELDS)
+    for i, (name, _) in STATVFS_FIELDS:
+        vals_w[i] = space.wrap(getattr(st, name))
+    w_tuple = space.newtuple(vals_w)
+    w_statvfs_result = space.getattr(space.getbuiltinmodule(os.name), 
space.wrap('statvfs_result'))
+    return space.call_function(w_statvfs_result, w_tuple)
+
+
 @unwrap_spec(fd=c_int)
 def fstat(space, fd):
     """Perform a stat system call on the file referenced to by an open
@@ -314,6 +327,26 @@
     else:
         state.stat_float_times = space.bool_w(w_value)
 
+
+@unwrap_spec(fd=c_int)
+def fstatvfs(space, fd):
+    try:
+        st = os.fstatvfs(fd)
+    except OSError as e:
+        raise wrap_oserror(space, e)
+    else:
+        return build_statvfs_result(space, st)
+
+
+def statvfs(space, w_path):
+    try:
+        st = dispatch_filename(rposix.statvfs)(space, w_path)
+    except OSError as e:
+        raise wrap_oserror2(space, e, w_path)
+    else:
+        return build_statvfs_result(space, st)
+
+
 @unwrap_spec(fd=c_int)
 def dup(space, fd):
     """Create a copy of the file descriptor.  Return the new file
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -169,7 +169,8 @@
         assert stat.S_ISDIR(st.st_mode)
 
     def test_stat_exception(self):
-        import sys, errno
+        import sys
+        import errno
         for fn in [self.posix.stat, self.posix.lstat]:
             try:
                 fn("nonexistentdir/nonexistentfile")
@@ -183,6 +184,15 @@
                     assert isinstance(e, WindowsError)
                     assert e.winerror == 3
 
+    def test_statvfs(self):
+        st = self.posix.statvfs(".")
+        assert isinstance(st, self.posix.statvfs_result)
+        for field in [
+            'f_bsize', 'f_frsize', 'f_blocks', 'f_bfree', 'f_bavail',
+            'f_files', 'f_ffree', 'f_favail', 'f_flag', 'f_namemax',
+        ]:
+            assert hasattr(st, field)
+
     def test_pickle(self):
         import pickle, os
         st = self.posix.stat(os.curdir)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -154,6 +154,15 @@
     else:
         return os.lstat(path.as_bytes())
 
+
+@specialize.argtype(0)
+def statvfs(path):
+    if isinstance(path, str):
+        return os.statvfs(path)
+    else:
+        return os.statvfs(path.as_bytes())
+
+
 @specialize.argtype(0)
 def unlink(path):
     if isinstance(path, str):
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -1698,6 +1698,17 @@
         from rpython.rtyper.module import ll_os_stat
         return ll_os_stat.register_stat_variant('lstat', traits)
 
+    @registering(os.fstatvfs)
+    def register_os_fstatvfs(self):
+        from rpython.rtyper.module import ll_os_stat
+        return ll_os_stat.register_statvfs_variant('fstatvfs', StringTraits())
+
+    @registering_str_unicode(os.statvfs)
+    def register_os_statvfs(self, traits):
+        from rpython.rtyper.module import ll_os_stat
+        return ll_os_stat.register_statvfs_variant('statvfs', traits)
+
+
     # ------------------------------- os.W* ---------------------------------
 
     w_star = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED',
diff --git a/rpython/rtyper/module/ll_os_stat.py 
b/rpython/rtyper/module/ll_os_stat.py
--- a/rpython/rtyper/module/ll_os_stat.py
+++ b/rpython/rtyper/module/ll_os_stat.py
@@ -2,20 +2,22 @@
 and os.fstat().  In RPython like in plain Python the stat result can be
 indexed like a tuple but also exposes the st_xxx attributes.
 """
-import os, sys
+
+import os
+import sys
+
 from rpython.annotator import model as annmodel
-from rpython.tool.pairtype import pairtype
-from rpython.tool.sourcetools import func_with_new_name, func_renamer
-from rpython.rtyper import extregistry
-from rpython.rtyper.extfunc import register_external, extdef
-from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rtyper.tool import rffi_platform as platform
-from rpython.rtyper.lltypesystem.rtupletype import TUPLE_TYPE
 from rpython.rlib import rposix
 from rpython.rlib.rarithmetic import intmask
-from rpython.rlib.objectmodel import specialize
+from rpython.rtyper import extregistry
+from rpython.rtyper.annlowlevel import hlstr
+from rpython.rtyper.extfunc import extdef
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem.rtupletype import TUPLE_TYPE
+from rpython.rtyper.tool import rffi_platform as platform
+from rpython.tool.pairtype import pairtype
+from rpython.tool.sourcetools import func_renamer
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rtyper.annlowlevel import hlstr
 
 # Support for float times is here.
 # - ALL_STAT_FIELDS contains Float fields if the system can retrieve
@@ -47,12 +49,26 @@
     ("st_flags",     lltype.Signed),
     #("st_gen",       lltype.Signed),     -- new in CPy 2.5, not implemented
     #("st_birthtime", lltype.Float),      -- new in CPy 2.5, not implemented
-    ]
+]
 N_INDEXABLE_FIELDS = 10
 
 # For OO backends, expose only the portable fields (the first 10).
 PORTABLE_STAT_FIELDS = ALL_STAT_FIELDS[:N_INDEXABLE_FIELDS]
 
+STATVFS_FIELDS = [
+    ("f_bsize", lltype.Signed),
+    ("f_frsize", lltype.Signed),
+    ("f_blocks", lltype.Signed),
+    ("f_bfree", lltype.Signed),
+    ("f_bavail", lltype.Signed),
+    ("f_files", lltype.Signed),
+    ("f_ffree", lltype.Signed),
+    ("f_favail", lltype.Signed),
+    ("f_flag", lltype.Signed),
+    ("f_namemax", lltype.Signed),
+]
+
+
 # ____________________________________________________________
 #
 # Annotation support
@@ -79,6 +95,7 @@
         def stat_result_reduce(st):
             return (st[0], st[1], st[2], st[3], st[4],
                     st[5], st[6], st[7], st[8], st[9])
+
         def stat_result_recreate(tup):
             return make_stat_result(tup + extra_zeroes)
         s_reduced = annmodel.SomeTuple([annmodel.lltype_to_annotation(TYPE)
@@ -86,6 +103,23 @@
         extra_zeroes = (0,) * (len(STAT_FIELDS) - len(PORTABLE_STAT_FIELDS))
         return s_reduced, stat_result_reduce, stat_result_recreate
 
+
+class SomeStatvfsResult(annmodel.SomeObject):
+    knowntype = os.statvfs_result
+
+    def rtyper_makerepr(self, rtyper):
+        from rpython.rtyper.module import r_os_stat
+        return r_os_stat.StatvfsResultRepr(rtyper)
+
+    def rtyper_makekey_ex(self, rtyper):
+        return self.__class__,
+
+    def getattr(self, s_attr):
+        assert s_attr.is_constant()
+        TYPE = STATVFS_FIELD_TYPES[s_attr.const]
+        return annmodel.lltype_to_annotation(TYPE)
+
+
 class __extend__(pairtype(SomeStatResult, annmodel.SomeInteger)):
     def getitem((s_sta, s_int)):
         assert s_int.is_constant(), "os.stat()[index]: index must be constant"
@@ -94,7 +128,17 @@
         name, TYPE = STAT_FIELDS[index]
         return annmodel.lltype_to_annotation(TYPE)
 
+
+class __extend__(pairtype(SomeStatvfsResult, annmodel.SomeInteger)):
+    def getitem((s_stat, s_int)):
+        assert s_int.is_constant()
+        name, TYPE = STATVFS_FIELDS[s_int.const]
+        return annmodel.lltype_to_annotation(TYPE)
+
+
 s_StatResult = SomeStatResult()
+s_StatvfsResult = SomeStatvfsResult()
+
 
 def make_stat_result(tup):
     """Turn a tuple into an os.stat_result object."""
@@ -104,6 +148,11 @@
         kwds[name] = tup[N_INDEXABLE_FIELDS + i]
     return os.stat_result(positional, kwds)
 
+
+def make_statvfs_result(tup):
+    return os.statvfs_result(tup)
+
+
 class MakeStatResultEntry(extregistry.ExtRegistryEntry):
     _about_ = make_stat_result
 
@@ -114,22 +163,33 @@
         from rpython.rtyper.module import r_os_stat
         return r_os_stat.specialize_make_stat_result(hop)
 
+
+class MakeStatvfsResultEntry(extregistry.ExtRegistryEntry):
+    _about_ = make_statvfs_result
+
+    def compute_result_annotation(self, s_tup):
+        return s_StatvfsResult
+
+    def specialize_call(self, hop):
+        from rpython.rtyper.module import r_os_stat
+        return r_os_stat.specialize_make_statvfs_result(hop)
+
 # ____________________________________________________________
 #
 # RFFI support
 
 if sys.platform.startswith('win'):
     _name_struct_stat = '_stati64'
-    INCLUDES = ['sys/types.h', 'sys/stat.h']
+    INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h']
 else:
     _name_struct_stat = 'stat'
-    INCLUDES = ['sys/types.h', 'sys/stat.h', 'unistd.h']
+    INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h', 'unistd.h']
 
 compilation_info = ExternalCompilationInfo(
     # This must be set to 64 on some systems to enable large file support.
     #pre_include_bits = ['#define _FILE_OFFSET_BITS 64'],
     # ^^^ nowadays it's always set in all C files we produce.
-    includes = INCLUDES
+    includes=INCLUDES
 )
 
 if TIMESPEC is not None:
@@ -141,7 +201,7 @@
 
 
 def posix_declaration(try_to_add=None):
-    global STAT_STRUCT
+    global STAT_STRUCT, STATVFS_STRUCT
 
     LL_STAT_FIELDS = STAT_FIELDS[:]
     if try_to_add:
@@ -173,15 +233,17 @@
     class CConfig:
         _compilation_info_ = compilation_info
         STAT_STRUCT = platform.Struct('struct %s' % _name_struct_stat, 
LL_STAT_FIELDS)
+        STATVFS_STRUCT = platform.Struct('struct statvfs', STATVFS_FIELDS)
+
     try:
-        config = platform.configure(CConfig, ignore_errors=
-                                    try_to_add is not None)
+        config = platform.configure(CConfig, ignore_errors=try_to_add is not 
None)
     except platform.CompilationError:
         if try_to_add:
             return    # failed to add this field, give up
         raise
 
     STAT_STRUCT = lltype.Ptr(config['STAT_STRUCT'])
+    STATVFS_STRUCT = lltype.Ptr(config['STATVFS_STRUCT'])
     if try_to_add:
         STAT_FIELDS.append(try_to_add)
 
@@ -202,6 +264,9 @@
 STAT_FIELD_NAMES = [_name for (_name, _TYPE) in STAT_FIELDS]
 del _name, _TYPE
 
+STATVFS_FIELD_TYPES = dict(STATVFS_FIELDS)
+STATVFS_FIELD_NAMES = [name for name, tp in STATVFS_FIELDS]
+
 
 def build_stat_result(st):
     # only for LL backends
@@ -233,6 +298,21 @@
     return make_stat_result(result)
 
 
+def build_statvfs_result(st):
+    return make_statvfs_result((
+        st.c_f_bsize,
+        st.c_f_frsize,
+        st.c_f_blocks,
+        st.c_f_bfree,
+        st.c_f_bavail,
+        st.c_f_files,
+        st.c_f_ffree,
+        st.c_f_favail,
+        st.c_f_flag,
+        st.c_f_namemax
+    ))
+
+
 def register_stat_variant(name, traits):
     if name != 'fstat':
         arg_is_path = True
@@ -301,6 +381,56 @@
         [s_arg], s_StatResult, "ll_os.ll_os_%s" % (name,),
         llimpl=posix_stat_llimpl, llfakeimpl=posix_fakeimpl)
 
+
+def register_statvfs_variant(name, traits):
+    if name != 'fstatvfs':
+        arg_is_path = True
+        s_arg = traits.str0
+        ARG1 = traits.CCHARP
+    else:
+        arg_is_path = False
+        s_arg = int
+        ARG1 = rffi.INT
+
+    posix_mystatvfs = rffi.llexternal(name,
+        [ARG1, STATVFS_STRUCT], rffi.INT,
+        compilation_info=compilation_info
+    )
+
+    @func_renamer('os_%s_llimpl' % (name,))
+    def posix_statvfs_llimpl(arg):
+        stresult = lltype.malloc(STATVFS_STRUCT.TO, flavor='raw')
+        try:
+            if arg_is_path:
+                arg = traits.str2charp(arg)
+            error = rffi.cast(rffi.LONG, posix_mystatvfs(arg, stresult))
+            if arg_is_path:
+                traits.free_charp(arg)
+            if error != 0:
+                raise OSError(rposix.get_errno(), "os_?statvfs failed")
+            return build_statvfs_result(stresult)
+        finally:
+            lltype.free(stresult, flavor='raw')
+
+    @func_renamer('os_%s_fake' % (name,))
+    def posix_fakeimpl(arg):
+        if s_arg == traits.str0:
+            arg = hlstr(arg)
+        st = getattr(os, name)(arg)
+        fields = [TYPE for fieldname, TYPE in STATVFS_FIELDS]
+        TP = TUPLE_TYPE(fields)
+        ll_tup = lltype.malloc(TP.TO)
+        for i, (fieldname, TYPE) in enumerate(STATVFS_FIELDS):
+            val = getattr(st, fieldname)
+            rffi.setintfield(ll_tup, 'item%d' % i, int(val))
+        return ll_tup
+
+    return extdef(
+        [s_arg], s_StatvfsResult, "ll_os.ll_os_%s" % (name,),
+        llimpl=posix_statvfs_llimpl, llfakeimpl=posix_fakeimpl
+    )
+
+
 def make_win32_stat_impl(name, traits):
     from rpython.rlib import rwin32
     from rpython.rtyper.module.ll_win32file import make_win32_traits
diff --git a/rpython/rtyper/module/r_os_stat.py 
b/rpython/rtyper/module/r_os_stat.py
--- a/rpython/rtyper/module/r_os_stat.py
+++ b/rpython/rtyper/module/r_os_stat.py
@@ -67,3 +67,52 @@
     # no-op conversion from r_StatResult.r_tuple to r_StatResult
     hop.exception_cannot_occur()
     return v_result
+
+
+class StatvfsResultRepr(Repr):
+
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+        self.statvfs_fields = ll_os_stat.STATVFS_FIELDS
+
+        self.statvfs_field_indexes = {}
+        for i, (name, TYPE) in enumerate(self.statvfs_fields):
+            self.statvfs_field_indexes[name] = i
+
+        self.s_tuple = annmodel.SomeTuple([annmodel.lltype_to_annotation(TYPE)
+                                           for name, TYPE in 
self.statvfs_fields])
+        self.r_tuple = rtyper.getrepr(self.s_tuple)
+        self.lowleveltype = self.r_tuple.lowleveltype
+
+    def redispatch_getfield(self, hop, index):
+        rtyper = self.rtyper
+        s_index = rtyper.annotator.bookkeeper.immutablevalue(index)
+        hop2 = hop.copy()
+        hop2.forced_opname = 'getitem'
+        hop2.args_v = [hop2.args_v[0], Constant(index)]
+        hop2.args_s = [self.s_tuple, s_index]
+        hop2.args_r = [self.r_tuple, rtyper.getrepr(s_index)]
+        return hop2.dispatch()
+
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        attr = s_attr.const
+        try:
+            index = self.statvfs_field_indexes[attr]
+        except KeyError:
+            raise TyperError("os.statvfs().%s: field not available" % (attr,))
+        return self.redispatch_getfield(hop, index)
+
+
+class __extend__(pairtype(StatvfsResultRepr, IntegerRepr)):
+    def rtype_getitem((r_sta, r_int), hop):
+        s_int = hop.args_s[1]
+        index = s_int.const
+        return r_sta.redispatch_getfield(hop, index)
+
+
+def specialize_make_statvfs_result(hop):
+    r_StatvfsResult = hop.rtyper.getrepr(ll_os_stat.s_StatvfsResult)
+    [v_result] = hop.inputargs(r_StatvfsResult.r_tuple)
+    hop.exception_cannot_occur()
+    return v_result
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to