[pypy-commit] pypy default: Issue #2820
arigo
pypy.commits at gmail.com
Sat May 12 03:14:46 EDT 2018
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r94526:a91492fa1e35
Date: 2018-05-12 09:14 +0200
http://bitbucket.org/pypy/pypy/changeset/a91492fa1e35/
Log: Issue #2820
Implement Py_ReprEnter() and Py_ReprLeave()
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -11,6 +11,7 @@
from pypy.module.cpyext.pyerrors import PyErr_NoMemory, PyErr_BadInternalCall
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.executioncontext import ExecutionContext
import pypy.module.__builtin__.operation as operation
@@ -411,3 +412,27 @@
def _PyPyGC_AddMemoryPressure(space, report):
from rpython.rlib import rgc
rgc.add_memory_pressure(report)
+
+
+ExecutionContext.cpyext_recursive_repr = None
+
+ at cpython_api([PyObject], rffi.INT_real, error=-1)
+def Py_ReprEnter(space, w_obj):
+ ec = space.getexecutioncontext()
+ d = ec.cpyext_recursive_repr
+ if d is None:
+ d = ec.cpyext_recursive_repr = {}
+ if w_obj in d:
+ return 1
+ d[w_obj] = None
+ return 0
+
+ at cpython_api([PyObject], lltype.Void)
+def Py_ReprLeave(space, w_obj):
+ ec = space.getexecutioncontext()
+ d = ec.cpyext_recursive_repr
+ if d is not None:
+ try:
+ del d[w_obj]
+ except KeyError:
+ pass
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -403,6 +403,47 @@
module.foo(35000)
assert self.cur_memory_pressure() == 65536 + 80000 + 70000
+ def test_repr_enter_leave(self):
+ module = self.import_extension('foo', [
+ ("enter", "METH_O",
+ """
+ return PyInt_FromLong(Py_ReprEnter(args));
+ """),
+ ("leave", "METH_O",
+ """
+ Py_ReprLeave(args);
+ Py_INCREF(Py_None);
+ return Py_None;
+ """)])
+ obj1 = [42]
+ obj2 = [42] # another list
+
+ n = module.enter(obj1)
+ assert n == 0
+ module.leave(obj1)
+
+ n = module.enter(obj1)
+ assert n == 0
+ n = module.enter(obj1)
+ assert n == 1
+ n = module.enter(obj1)
+ assert n == 1
+ module.leave(obj1)
+
+ n = module.enter(obj1)
+ assert n == 0
+ n = module.enter(obj2)
+ assert n == 0
+ n = module.enter(obj1)
+ assert n == 1
+ n = module.enter(obj2)
+ assert n == 1
+ module.leave(obj1)
+ n = module.enter(obj2)
+ assert n == 1
+ module.leave(obj2)
+
+
class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
"""
PyBuffer_FillInfo populates the fields of a Py_buffer from its arguments.
More information about the pypy-commit
mailing list