[pypy-svn] r45676 - in pypy/branch/pypy-more-rtti-inprogress: rpython/module translator/c/test

arigo at codespeak.net arigo at codespeak.net
Wed Aug 15 14:09:46 CEST 2007


Author: arigo
Date: Wed Aug 15 14:09:44 2007
New Revision: 45676

Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os_environ.py
   pypy/branch/pypy-more-rtti-inprogress/translator/c/test/test_extfunc.py
Log:
Support for os.environ.keys() and os.environ.items().  Not tested on OS/X.


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os_environ.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os_environ.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os_environ.py	Wed Aug 15 14:09:44 2007
@@ -22,6 +22,14 @@
         # in the RPython program, 'os.environ[key] = value' is redirected here
         r_putenv(key, value)
 
+    def get_keys(self, obj):
+        # 'os.environ.keys' is redirected here - note that it's the getattr
+        # that arrives here, not the actual method call!
+        return r_envkeys
+
+    def get_items(self, obj):
+        # 'os.environ.items' is redirected here (not the actual method call!)
+        return r_envitems
 
 # ____________________________________________________________
 #
@@ -73,3 +81,58 @@
 _register_external(r_putenv, [str, str], annmodel.s_None,
                    export_name='ll_os.ll_os_putenv',
                    llimpl=putenv_lltypeimpl)
+
+# ____________________________________________________________
+# Access to the 'environ' external variable
+
+if os.name.startswith('darwin'):
+    CCHARPPP = lltype.Ptr(lltype.FixedSizeArray(rffi.CCHARPP, 1))
+    _os_NSGetEnviron = rffi.llexternal('_NSGetEnviron', [], CCHARPPP,
+                                       includes=['crt_externs.h'])
+    def os_get_environ():
+        return _os_NSGetEnviron()[0]
+else:
+    os_get_environ, _os_set_environ = rffi.CExternVariable(rffi.CCHARPP,
+                                                           'environ')
+
+# ____________________________________________________________
+
+def r_envkeys():
+    just_a_placeholder
+
+def envkeys_lltypeimpl():
+    environ = os_get_environ()
+    result = []
+    i = 0
+    while environ[i]:
+        name_value = rffi.charp2str(environ[i])
+        p = name_value.find('=')
+        if p >= 0:
+            result.append(name_value[:p])
+        i += 1
+    return result
+
+_register_external(r_envkeys, [], [str],   # returns a list of strings
+                   export_name='ll_os.ll_os_envkeys',
+                   llimpl=envkeys_lltypeimpl)
+
+# ____________________________________________________________
+
+def r_envitems():
+    just_a_placeholder
+
+def envitems_lltypeimpl():
+    environ = os_get_environ()
+    result = []
+    i = 0
+    while environ[i]:
+        name_value = rffi.charp2str(environ[i])
+        p = name_value.find('=')
+        if p >= 0:
+            result.append((name_value[:p], name_value[p+1:]))
+        i += 1
+    return result
+
+_register_external(r_envitems, [], [(str, str)],
+                   export_name='ll_os.ll_os_envitems',
+                   llimpl=envitems_lltypeimpl)

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/c/test/test_extfunc.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/c/test/test_extfunc.py	Wed Aug 15 14:09:44 2007
@@ -704,6 +704,39 @@
          expected_extra_mallocs = (1, 2, 3, 4))   # at least one, less than 5
     assert _real_getenv('PYPY_TEST_DICTLIKE_ENVIRON') == '42'
 
+def test_dictlike_environ_keys():
+    def fn():
+        return '\x00'.join(os.environ.keys())
+    func = compile(fn, [])
+    os.environ.setdefault('USER', 'UNNAMED_USER')
+    try:
+        del os.environ['PYPY_TEST_DICTLIKE_ENVKEYS']
+    except:
+        pass
+    result1 = func().split('\x00')
+    os.environ['PYPY_TEST_DICTLIKE_ENVKEYS'] = '42'
+    result2 = func().split('\x00')
+    assert 'USER' in result1
+    assert 'PYPY_TEST_DICTLIKE_ENVKEYS' not in result1
+    assert 'USER' in result2
+    assert 'PYPY_TEST_DICTLIKE_ENVKEYS' in result2
+
+def test_dictlike_environ_items():
+    def fn():
+        result = []
+        for key, value in os.environ.items():
+            result.append('%s/%s' % (key, value))
+        return '\x00'.join(result)
+    func = compile(fn, [])
+    os.environ.setdefault('USER', 'UNNAMED_USER')
+    result1 = func().split('\x00')
+    os.environ['PYPY_TEST_DICTLIKE_ENVITEMS'] = '783'
+    result2 = func().split('\x00')
+    assert ('USER/%s' % (os.environ['USER'],)) in result1
+    assert 'PYPY_TEST_DICTLIKE_ENVITEMS/783' not in result1
+    assert ('USER/%s' % (os.environ['USER'],)) in result2
+    assert 'PYPY_TEST_DICTLIKE_ENVITEMS/783' in result2
+
 
 def test_opendir_readdir():
     py.test.skip("deprecated")



More information about the Pypy-commit mailing list