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