Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r95244:c7d3ff6df4ef
Date: 2018-10-25 18:31 +0200
http://bitbucket.org/pypy/pypy/changeset/c7d3ff6df4ef/

Log:    hg merge default

diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -27,6 +27,12 @@
 from .console import Console, Event
 from .unix_eventqueue import EventQueue
 from .trace import trace
+try:
+    from __pypy__ import pyos_inputhook
+except ImportError:
+    def pyos_inputhook():
+        pass
+
 
 class InvalidTerminal(RuntimeError):
     pass
@@ -76,8 +82,8 @@
             pass
         def register(self, fd, flag):
             self.fd = fd
-        def poll(self, timeout=None):
-            r,w,e = select.select([self.fd],[],[],timeout)
+        def poll(self):   # note: a 'timeout' argument would be *milliseconds*
+            r,w,e = select.select([self.fd],[],[])
             return r
 
 POLLIN = getattr(select, "POLLIN", None)
@@ -407,6 +413,7 @@
     def get_event(self, block=1):
         while self.event_queue.empty():
             while 1: # All hail Unix!
+                pyos_inputhook()
                 try:
                     self.push_char(os.read(self.input_fd, 1))
                 except (IOError, OSError) as err:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -110,6 +110,7 @@
         'stack_almost_full'         : 'interp_magic.stack_almost_full',
         'fsencode'                  : 'interp_magic.fsencode',
         'fsdecode'                  : 'interp_magic.fsdecode',
+        'pyos_inputhook'            : 'interp_magic.pyos_inputhook',
     }
 
     submodules = {
diff --git a/pypy/module/__pypy__/interp_magic.py 
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -209,3 +209,13 @@
 def revdb_stop(space):
     from pypy.interpreter.reverse_debugging import stop_point
     stop_point()
+
+def pyos_inputhook(space):
+    """Call PyOS_InputHook() from the CPython C API."""
+    if not space.config.objspace.usemodules.cpyext:
+        return
+    w_modules = space.sys.get('modules')
+    if space.finditem_str(w_modules, 'cpyext') is None:
+        return      # cpyext not imported yet, ignore
+    from pypy.module.cpyext.api import invoke_pyos_inputhook
+    invoke_pyos_inputhook(space)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -647,6 +647,7 @@
     'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 
'Py_IgnoreEnvironmentFlag',
     'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 
'Py_NoUserSiteDirectory',
     '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', 
'_Py_PackageContext',
+    'PyOS_InputHook',
 
     'PyMem_RawMalloc', 'PyMem_RawCalloc', 'PyMem_RawRealloc', 'PyMem_RawFree',
     'PyMem_Malloc', 'PyMem_Calloc', 'PyMem_Realloc', 'PyMem_Free',
@@ -1183,6 +1184,10 @@
     state.C._PyPy_object_dealloc = rffi.llexternal(
         '_PyPy_object_dealloc', [PyObject], lltype.Void,
         compilation_info=eci, _nowrapper=True)
+    FUNCPTR = lltype.Ptr(lltype.FuncType([], rffi.INT))
+    state.C.get_pyos_inputhook = rffi.llexternal(
+        '_PyPy_get_PyOS_InputHook', [], FUNCPTR,
+        compilation_info=eci, _nowrapper=True)
 
 
 def init_function(func):
@@ -1789,6 +1794,12 @@
             return
         return exec_def(space, w_mod, mod_as_pyobj)
 
+def invoke_pyos_inputhook(space):
+    state = space.fromcache(State)
+    c_inputhook = state.C.get_pyos_inputhook()
+    if c_inputhook:
+        generic_cpy_call(space, c_inputhook)
+
 @specialize.ll()
 def generic_cpy_call(space, func, *args):
     FT = lltype.typeOf(func).TO
diff --git a/pypy/module/cpyext/include/pythonrun.h 
b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -41,6 +41,11 @@
 
 #define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, 
filename, start, NULL)
 
+/* Stuff with no proper home (yet) */
+PyAPI_DATA(int) (*PyOS_InputHook)(void);
+typedef int (*_pypy_pyos_inputhook)(void);
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c
--- a/pypy/module/cpyext/src/missing.c
+++ b/pypy/module/cpyext/src/missing.c
@@ -31,3 +31,7 @@
 void _Py_setfilesystemdefaultencoding(const char *enc) {
     Py_FileSystemDefaultEncoding = enc;
 }
+int (*PyOS_InputHook)(void) = 0;  /* only ever filled in by C extensions */
+PyAPI_FUNC(_pypy_pyos_inputhook) _PyPy_get_PyOS_InputHook(void) {
+    return PyOS_InputHook;
+}
diff --git a/pypy/module/cpyext/test/test_misc.py 
b/pypy/module/cpyext/test/test_misc.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_misc.py
@@ -0,0 +1,35 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+
+class AppTestMisc(AppTestCpythonExtensionBase):
+
+    def test_pyos_inputhook(self):
+        module = self.import_extension('foo', [
+               ("set_pyos_inputhook", "METH_NOARGS",
+                '''
+                    PyOS_InputHook = &my_callback;
+                    Py_RETURN_NONE;
+                '''),
+                ("fetch_value", "METH_NOARGS",
+                '''
+                    return PyLong_FromLong(my_flag);
+                '''),
+            ], prologue='''
+            static long my_flag = 0;
+            static int my_callback(void) { my_flag++; }
+            ''')
+
+        try:
+            import __pypy__
+        except ImportError:
+            skip("only runs on top of pypy")
+        assert module.fetch_value() == 0
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 0
+        module.set_pyos_inputhook()       # <= set
+        assert module.fetch_value() == 0
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 1
+        __pypy__.pyos_inputhook()
+        assert module.fetch_value() == 2
+        assert module.fetch_value() == 2
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to