Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r44133:12b3ef758f0d
Date: 2011-05-13 15:40 +0200
http://bitbucket.org/pypy/pypy/changeset/12b3ef758f0d/

Log:    merge heads

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -12,9 +12,21 @@
     appleveldefs = {
     }
 
+    atexit_funcs = []
+
     def startup(self, space):
         space.fromcache(State).startup(space)
 
+    def register_atexit(self, function):
+        if len(self.atexit_funcs) >= 32:
+            raise ValueError("cannot register more than 32 atexit functions")
+        self.atexit_funcs.append(function)
+
+    def shutdown(self, space):
+        for func in self.atexit_funcs:
+            func()
+
+
 # import these modules to register api functions by side-effect
 import pypy.module.cpyext.thread
 import pypy.module.cpyext.pyobject
diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py
--- a/pypy/module/cpyext/import_.py
+++ b/pypy/module/cpyext/import_.py
@@ -73,3 +73,10 @@
         w_mod = Module(space, space.wrap(modulename))
     return borrow_from(None, w_mod)
 
+@cpython_api([], PyObject)
+def PyImport_GetModuleDict(space):
+    """Return the dictionary used for the module administration (a.k.a.
+    sys.modules).  Note that this is a per-interpreter variable."""
+    w_modulesDict = space.sys.get('modules')
+    return borrow_from(None, w_modulesDict)
+
diff --git a/pypy/module/cpyext/pythonrun.py b/pypy/module/cpyext/pythonrun.py
--- a/pypy/module/cpyext/pythonrun.py
+++ b/pypy/module/cpyext/pythonrun.py
@@ -14,3 +14,21 @@
     value."""
     return space.fromcache(State).get_programname()
 
+@cpython_api([lltype.Ptr(lltype.FuncType([], lltype.Void))], rffi.INT_real, 
error=-1)
+def Py_AtExit(space, func_ptr):
+    """Register a cleanup function to be called by Py_Finalize().  The cleanup
+    function will be called with no arguments and should return no value.  At
+    most 32 cleanup functions can be registered.  When the registration is
+    successful, Py_AtExit() returns 0; on failure, it returns -1.  The cleanup
+    function registered last is called first. Each cleanup function will be
+    called at most once.  Since Python's internal finalization will have
+    completed before the cleanup function, no Python APIs should be called by
+    func."""
+    from pypy.module import cpyext
+    w_module = space.getbuiltinmodule('cpyext')
+    module = space.interp_w(cpyext.Module, w_module)
+    try:
+        module.register_atexit(func_ptr)
+    except ValueError:
+        return -1
+    return 0
diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py
--- a/pypy/module/cpyext/sequence.py
+++ b/pypy/module/cpyext/sequence.py
@@ -36,7 +36,6 @@
 def PySequence_Length(space, w_obj):
     return space.len_w(w_obj)
 
-
 @cpython_api([PyObject, CONST_STRING], PyObject)
 def PySequence_Fast(space, w_obj, m):
     """Returns the sequence o as a tuple, unless it is already a tuple or 
list, in
@@ -96,10 +95,21 @@
     return 0
 
 @cpython_api([PyObject, Py_ssize_t], PyObject)
+def PySequence_ITEM(space, w_obj, i):
+    """Return the ith element of o or NULL on failure. Macro form of
+    PySequence_GetItem() but without checking that
+    PySequence_Check(o)() is true and without adjustment for negative
+    indices.
+
+    This function used an int type for i. This might require
+    changes in your code for properly supporting 64-bit systems."""
+    return space.getitem(w_obj, space.wrap(i))
+
+@cpython_api([PyObject, Py_ssize_t], PyObject)
 def PySequence_GetItem(space, w_obj, i):
     """Return the ith element of o, or NULL on failure. This is the equivalent 
of
     the Python expression o[i]."""
-    return space.getitem(w_obj, space.wrap(i))
+    return PySequence_ITEM(space, w_obj, i)
 
 @cpython_api([PyObject], PyObject)
 def PySequence_List(space, w_obj):
@@ -154,3 +164,26 @@
     equivalent of the Python statement del o[i]."""
     space.delitem(w_o, space.wrap(i))
     return 0
+
+@cpython_api([PyObject, PyObject], Py_ssize_t, error=-1)
+def PySequence_Index(space, w_seq, w_obj):
+    """Return the first index i for which o[i] == value.  On error, return
+    -1.    This is equivalent to the Python expression o.index(value).
+
+    This function returned an int type. This might require changes
+    in your code for properly supporting 64-bit systems."""
+
+    w_iter = space.iter(w_seq)
+    idx = 0
+    while True:
+        try:
+            w_next = space.next(w_iter)
+        except OperationError, e:
+            if e.match(space, space.w_StopIteration):
+                break
+            raise
+        if space.is_true(space.eq(w_next, w_obj)):
+            return idx
+        idx += 1
+
+    return -1
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -2021,15 +2021,6 @@
     in your code for properly supporting 64-bit systems."""
     raise NotImplementedError
 
-@cpython_api([PyObject, PyObject], Py_ssize_t, error=-1)
-def PySequence_Index(space, o, value):
-    """Return the first index i for which o[i] == value.  On error, return
-    -1.    This is equivalent to the Python expression o.index(value).
-
-    This function returned an int type. This might require changes
-    in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], PyObjectP)
 def PySequence_Fast_ITEMS(space, o):
     """Return the underlying array of PyObject pointers.  Assumes that o was 
returned
@@ -2041,17 +2032,6 @@
     """
     raise NotImplementedError
 
-@cpython_api([PyObject, Py_ssize_t], PyObject)
-def PySequence_ITEM(space, o, i):
-    """Return the ith element of o or NULL on failure. Macro form of
-    PySequence_GetItem() but without checking that
-    PySequence_Check(o)() is true and without adjustment for negative
-    indices.
-
-    This function used an int type for i. This might require
-    changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def PySet_Check(space, p):
     """Return true if p is a set object or an instance of a subtype.
@@ -2274,18 +2254,6 @@
     standard C library function exit(status)."""
     raise NotImplementedError
 
-@cpython_api([rffi.VOIDP], rffi.INT_real, error=-1)
-def Py_AtExit(space, func):
-    """Register a cleanup function to be called by Py_Finalize().  The cleanup
-    function will be called with no arguments and should return no value.  At
-    most 32 cleanup functions can be registered.  When the registration is
-    successful, Py_AtExit() returns 0; on failure, it returns -1.  The cleanup
-    function registered last is called first. Each cleanup function will be
-    called at most once.  Since Python's internal finalization will have
-    completed before the cleanup function, no Python APIs should be called by
-    func."""
-    raise NotImplementedError
-
 @cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
 def PyTuple_GetSlice(space, p, low, high):
     """Take a slice of the tuple pointed to by p from low to high and return it
diff --git a/pypy/module/cpyext/test/test_eval.py 
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -166,6 +166,15 @@
 
         lltype.free(pi, flavor='raw')
 
+    def test_atexit(self, space, api):
+        lst = []
+        def func():
+            lst.append(42)
+        api.Py_AtExit(func)
+        cpyext = space.getbuiltinmodule('cpyext')
+        cpyext.shutdown(space) # simulate shutdown
+        assert lst == [42]
+
 class AppTestCall(AppTestCpythonExtensionBase):
     def test_CallFunction(self):
         module = self.import_extension('foo', [
diff --git a/pypy/module/cpyext/test/test_import.py 
b/pypy/module/cpyext/test/test_import.py
--- a/pypy/module/cpyext/test/test_import.py
+++ b/pypy/module/cpyext/test/test_import.py
@@ -18,6 +18,19 @@
         assert space.str_w(space.getattr(w_foobar,
                                          space.wrap('__name__'))) == 'foobar'
 
+    def test_getmoduledict(self, space, api):
+        testmod = "binascii"
+        w_pre_dict = api.PyImport_GetModuleDict()
+        assert not space.is_true(space.contains(w_pre_dict, 
space.wrap(testmod)))
+
+        with rffi.scoped_str2charp(testmod) as modname:
+            w_module = api.PyImport_ImportModule(modname)
+            print w_module
+            assert w_module
+
+        w_dict = api.PyImport_GetModuleDict()
+        assert space.is_true(space.contains(w_dict, space.wrap(testmod)))
+
     def test_reload(self, space, api):
         pdb = api.PyImport_Import(space.wrap("pdb"))
         space.delattr(pdb, space.wrap("set_trace"))
diff --git a/pypy/module/cpyext/test/test_sequence.py 
b/pypy/module/cpyext/test/test_sequence.py
--- a/pypy/module/cpyext/test/test_sequence.py
+++ b/pypy/module/cpyext/test/test_sequence.py
@@ -105,3 +105,32 @@
 
         self.raises(space, api, IndexError, api.PySequence_DelItem,
                     w_l, 3)
+
+    def test_getitem(self, space, api):
+        thelist = [8, 7, 6, 5, 4, 3, 2, 1]
+        w_l = space.wrap(thelist)
+
+        result = api.PySequence_GetItem(w_l, 4)
+        assert space.is_true(space.eq(result, space.wrap(4)))
+
+        result = api.PySequence_ITEM(w_l, 4)
+        assert space.is_true(space.eq(result, space.wrap(4)))
+
+        self.raises(space, api, IndexError, api.PySequence_GetItem, w_l, 9000)
+
+    def test_index(self, space, api):
+        thelist = [9, 8, 7, 6, 5, 4, 3, 2, 1]
+        w_l = space.wrap(thelist)
+        w_tofind = space.wrap(5)
+
+        result = api.PySequence_Index(w_l, w_tofind)
+        assert result == thelist.index(5)
+
+        w_tofind = space.wrap(9001)
+        result = api.PySequence_Index(w_l, w_tofind)
+        assert result == -1
+
+        gen = (x ** 2 for x in range(40))
+        w_tofind = space.wrap(16)
+        result = api.PySequence_Index(space.wrap(gen), w_tofind)
+        assert result == 4
diff --git a/pypy/rpython/memory/gctransform/framework.py 
b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -714,8 +714,7 @@
                     malloc_ptr = self.malloc_varsize_clear_ptr
                 args = [self.c_const_gc, c_type_id, v_length, c_size,
                         c_varitemsize, c_ofstolength, c_can_collect]
-        keep_current_args = flags.get('keep_current_args', False)
-        livevars = self.push_roots(hop, keep_current_args=keep_current_args)
+        livevars = self.push_roots(hop)
         v_result = hop.genop("direct_call", [malloc_ptr] + args,
                              resulttype=llmemory.GCREF)
         self.pop_roots(hop, livevars)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to