[pypy-svn] r45677 - in pypy/branch/pypy-more-rtti-inprogress: rpython rpython/module translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Wed Aug 15 14:29:34 CEST 2007
Author: arigo
Date: Wed Aug 15 14:29:32 2007
New Revision: 45677
Modified:
pypy/branch/pypy-more-rtti-inprogress/rpython/controllerentry.py
pypy/branch/pypy-more-rtti-inprogress/rpython/module/ll_os_environ.py
pypy/branch/pypy-more-rtti-inprogress/rpython/rcontrollerentry.py
pypy/branch/pypy-more-rtti-inprogress/translator/c/test/test_extfunc.py
Log:
Support for del os.environ[name]
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/controllerentry.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/controllerentry.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/controllerentry.py Wed Aug 15 14:29:32 2007
@@ -117,6 +117,13 @@
from pypy.rpython.rcontrollerentry import rtypedelegate
return rtypedelegate(self.setitem, hop)
+ def ctrl_delitem(self, s_obj, s_key):
+ return delegate(self.delitem, s_obj, s_key)
+
+ def rtype_delitem(self, hop):
+ from pypy.rpython.rcontrollerentry import rtypedelegate
+ return rtypedelegate(self.delitem, hop)
+
def ctrl_is_true(self, s_obj):
return delegate(self.is_true, s_obj)
@@ -237,6 +244,9 @@
def setitem((s_cin, s_key), s_value):
s_cin.controller.ctrl_setitem(s_cin.s_real_obj, s_key, s_value)
+ def delitem((s_cin, s_key)):
+ s_cin.controller.ctrl_delitem(s_cin.s_real_obj, s_key)
+
class __extend__(pairtype(SomeControlledInstance, SomeControlledInstance)):
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:29:32 2007
@@ -22,6 +22,10 @@
# in the RPython program, 'os.environ[key] = value' is redirected here
r_putenv(key, value)
+ def delitem(self, obj, key):
+ # in the RPython program, 'del os.environ[key]' is redirected here
+ r_unsetenv(key)
+
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!
@@ -70,6 +74,7 @@
l_string = rffi.str2charp('%s=%s' % (name, value))
error = os_putenv(l_string)
if error:
+ rffi.free_charp(l_string)
raise OSError(rffi.get_errno(), "os_putenv failed")
# keep 'l_string' alive - we know that the C library needs it
# until the next call to putenv() with the same 'name'.
@@ -83,6 +88,34 @@
llimpl=putenv_lltypeimpl)
# ____________________________________________________________
+
+def r_unsetenv(name):
+ # default implementation for platforms without a real unsetenv()
+ r_putenv(name, '')
+
+if hasattr(__import__(os.name), 'unsetenv'):
+
+ os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT)
+
+ def unsetenv_lltypeimpl(name):
+ l_name = rffi.str2charp(name)
+ error = os_unsetenv(l_name)
+ rffi.free_charp(l_name)
+ if error:
+ raise OSError(rffi.get_errno(), "os_unsetenv failed")
+ try:
+ l_oldstring = envkeepalive.byname[name]
+ except KeyError:
+ pass
+ else:
+ del envkeepalive.byname[name]
+ rffi.free_charp(l_oldstring)
+
+ _register_external(r_unsetenv, [str], annmodel.s_None,
+ export_name='ll_os.ll_os_unsetenv',
+ llimpl=unsetenv_lltypeimpl)
+
+# ____________________________________________________________
# Access to the 'environ' external variable
if os.name.startswith('darwin'):
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/rcontrollerentry.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/rcontrollerentry.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/rcontrollerentry.py Wed Aug 15 14:29:32 2007
@@ -40,6 +40,9 @@
def rtype_setitem((r_controlled, r_key), hop):
return r_controlled.controller.rtype_setitem(hop)
+ def rtype_delitem((r_controlled, r_key), hop):
+ return r_controlled.controller.rtype_delitem(hop)
+
def rtypedelegate(callable, hop, revealargs=[0], revealresult=False):
bk = hop.rtyper.annotator.bookkeeper
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:29:32 2007
@@ -701,9 +701,44 @@
os.environ[s] = t5
func = compile(fn, [str, str, str, str, str, str])
func('PYPY_TEST_DICTLIKE_ENVIRON', 'a', 'b', 'c', 'FOOBAR', '42',
- expected_extra_mallocs = (1, 2, 3, 4)) # at least one, less than 5
+ expected_extra_mallocs = (2, 3, 4)) # at least two, less than 5
assert _real_getenv('PYPY_TEST_DICTLIKE_ENVIRON') == '42'
+def test_dictlike_environ_delitem():
+ def fn(s1, s2, s3, s4, s5):
+ for n in range(10):
+ os.environ[s1] = 't1'
+ os.environ[s2] = 't2'
+ os.environ[s3] = 't3'
+ os.environ[s4] = 't4'
+ os.environ[s5] = 't5'
+ del os.environ[s3]
+ del os.environ[s1]
+ del os.environ[s2]
+ del os.environ[s4]
+ # os.environ[s5] stays
+ func = compile(fn, [str, str, str, str, str])
+ if hasattr(__import__(os.name), 'unsetenv'):
+ expected_extra_mallocs = range(2, 10)
+ # at least 2, less than 10: memory for s1, s2, s3, s4 should be freed
+ # (each kept-alive entry counts as two: the RPython string used as
+ # key in 'envkeepalive.byname' and the raw-allocated char* as value)
+ else:
+ expected_extra_mallocs = range(10, 18)
+ # at least 10, less than 18: memory for the initial s1, s2, s3, s4
+ # should be freed, but replaced by new buffers for empty strings
+ func('PYPY_TEST_DICTLIKE_ENVDEL1',
+ 'PYPY_TEST_DICTLIKE_ENVDEL_X',
+ 'PYPY_TEST_DICTLIKE_ENVDELFOO',
+ 'PYPY_TEST_DICTLIKE_ENVDELBAR',
+ 'PYPY_TEST_DICTLIKE_ENVDEL5',
+ expected_extra_mallocs = expected_extra_mallocs)
+ assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL1')
+ assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL_X')
+ assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDELFOO')
+ assert not _real_getenv('PYPY_TEST_DICTLIKE_ENVDELBAR')
+ assert _real_getenv('PYPY_TEST_DICTLIKE_ENVDEL5') == 't5'
+
def test_dictlike_environ_keys():
def fn():
return '\x00'.join(os.environ.keys())
More information about the Pypy-commit
mailing list