Author: Matti Picus <matti.pi...@gmail.com>
Branch: release-pypy3.5-5.x
Changeset: r92481:24686d8f9ef3
Date: 2017-09-27 21:18 +0300
http://bitbucket.org/pypy/pypy/changeset/24686d8f9ef3/

Log:    merge py3.5 into branch

diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -12,7 +12,8 @@
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.astcompiler.consts import (
     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-    CO_GENERATOR, CO_COROUTINE, CO_KILL_DOCSTRING, CO_YIELD_INSIDE_TRY)
+    CO_GENERATOR, CO_COROUTINE, CO_KILL_DOCSTRING, CO_YIELD_INSIDE_TRY,
+    CO_ITERABLE_COROUTINE)
 from pypy.tool import dis3
 from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
 from rpython.rlib.rarithmetic import intmask
diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py
--- a/pypy/module/_socket/__init__.py
+++ b/pypy/module/_socket/__init__.py
@@ -37,7 +37,8 @@
             CMSG_SPACE CMSG_LEN
             """.split():
 
-            if (name in ('inet_pton', 'inet_ntop', 'socketpair') and
+            if (name in ('inet_pton', 'inet_ntop', 'socketpair',
+                         'CMSG_SPACE', 'CMSG_LEN') and
                 not hasattr(rsocket, name)):
                 continue
 
diff --git a/pypy/module/_socket/interp_func.py 
b/pypy/module/_socket/interp_func.py
--- a/pypy/module/_socket/interp_func.py
+++ b/pypy/module/_socket/interp_func.py
@@ -1,3 +1,4 @@
+import sys
 from rpython.rlib import rsocket
 from rpython.rlib.rsocket import SocketError, INVALID_SOCKET
 from rpython.rlib.rarithmetic import intmask, r_longlong, r_uint32
@@ -327,41 +328,42 @@
             for (family, socktype, protocol, canonname, addr) in lst]
     return space.newlist(lst1)
 
-@unwrap_spec(size=int)
-def CMSG_SPACE(space, size):
-    """
-    Socket method to determine the optimal byte size of the ancillary.
-    Recommended to be used when computing the ancillary size for recvmsg.
-    :param space:
-    :param size: an integer with the minimum size required.
-    :return: an integer with the minimum memory needed for the required size. 
The value is memory alligned
-    """
-    if size < 0:
-        raise oefmt(space.w_OverflowError,
-                    "CMSG_SPACE() argument out of range")
-    retval = rsocket.CMSG_SPACE(size)
-    if retval == 0:
-        raise oefmt(space.w_OverflowError,
-                    "CMSG_SPACE() argument out of range")
-    return space.newint(retval)
+if sys.platform != 'win32':
+    @unwrap_spec(size=int)
+    def CMSG_SPACE(space, size):
+        """
+        Socket method to determine the optimal byte size of the ancillary.
+        Recommended to be used when computing the ancillary size for recvmsg.
+        :param space:
+        :param size: an integer with the minimum size required.
+        :return: an integer with the minimum memory needed for the required 
size. The value is memory alligned
+        """
+        if size < 0:
+            raise oefmt(space.w_OverflowError,
+                        "CMSG_SPACE() argument out of range")
+        retval = rsocket.CMSG_SPACE(size)
+        if retval == 0:
+            raise oefmt(space.w_OverflowError,
+                        "CMSG_SPACE() argument out of range")
+        return space.newint(retval)
 
-@unwrap_spec(len=int)
-def CMSG_LEN(space, len):
-    """
-    Socket method to determine the optimal byte size of the ancillary.
-    Recommended to be used when computing the ancillary size for recvmsg.
-    :param space:
-    :param len: an integer with the minimum size required.
-    :return: an integer with the minimum memory needed for the required size. 
The value is not mem alligned.
-    """
-    if len < 0:
-        raise oefmt(space.w_OverflowError,
-                    "CMSG_LEN() argument out of range")
-    retval = rsocket.CMSG_LEN(len)
-    if retval == 0:
-        raise oefmt(space.w_OverflowError,
-                    "CMSG_LEN() argument out of range")
-    return space.newint(retval)
+    @unwrap_spec(len=int)
+    def CMSG_LEN(space, len):
+        """
+        Socket method to determine the optimal byte size of the ancillary.
+        Recommended to be used when computing the ancillary size for recvmsg.
+        :param space:
+        :param len: an integer with the minimum size required.
+        :return: an integer with the minimum memory needed for the required 
size. The value is not mem alligned.
+        """
+        if len < 0:
+            raise oefmt(space.w_OverflowError,
+                        "CMSG_LEN() argument out of range")
+        retval = rsocket.CMSG_LEN(len)
+        if retval == 0:
+            raise oefmt(space.w_OverflowError,
+                        "CMSG_LEN() argument out of range")
+        return space.newint(retval)
 
 def getdefaulttimeout(space):
     """getdefaulttimeout() -> timeout
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -879,11 +879,14 @@
 socketmethodnames = """
 _accept bind close connect connect_ex fileno detach
 getpeername getsockname getsockopt gettimeout listen
-recv recvfrom recvmsg send sendall sendto sendmsg setblocking
+recv recvfrom send sendall sendto setblocking
 setsockopt settimeout shutdown _reuse _drop recv_into recvfrom_into
 """.split()
 if hasattr(rsocket._c, 'WSAIoctl'):
     socketmethodnames.append('ioctl')
+if rsocket._c.HAVE_SENDMSG:
+    socketmethodnames.append('sendmsg')
+    socketmethodnames.append('recvmsg')
 
 socketmethods = {}
 for methodname in socketmethodnames:
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -18,6 +18,8 @@
     CO_VARKEYWORDS = 0x0008,
     CO_NESTED      = 0x0010,
     CO_GENERATOR   = 0x0020,
+    CO_COROUTINE=0x0080,
+    CO_ITERABLE_COROUTINE=0x0100,
 )
 ALL_CODE_FLAGS = unrolling_iterable(CODE_FLAGS.items())
 
diff --git a/pypy/module/cpyext/genobject.py b/pypy/module/cpyext/genobject.py
--- a/pypy/module/cpyext/genobject.py
+++ b/pypy/module/cpyext/genobject.py
@@ -1,7 +1,32 @@
+from rpython.rtyper.lltypesystem import lltype
 from pypy.interpreter.generator import GeneratorIterator, Coroutine
-from pypy.module.cpyext.api import build_type_checkers
+from pypy.module.cpyext.api import (
+    build_type_checkers, cts, parse_dir, bootstrap_function, slot_function)
+from pypy.module.cpyext.pyobject import PyObject, make_typedescr, as_pyobj
+from pypy.module.cpyext.object import _dealloc
+
+cts.parse_header(parse_dir / 'cpyext_genobject.h')
+
+@bootstrap_function
+def init_genobject(space):
+    make_typedescr(GeneratorIterator.typedef,
+                   basestruct=cts.gettype('PyGenObject'),
+                   attach=gi_attach,
+                   dealloc=gi_dealloc)
 
 
 PyGen_Check, PyGen_CheckExact = build_type_checkers("Gen", GeneratorIterator)
 
 _, PyCoro_CheckExact = build_type_checkers("Coro", Coroutine)
+
+def gi_attach(space, py_obj, w_obj, w_userdata=None):
+    assert isinstance(w_obj, GeneratorIterator)
+    cts.cast('PyGenObject*', py_obj).c_gi_code = as_pyobj(space, w_obj.pycode)
+
+def gi_realize(space, py_obj):
+    raise NotImplementedError(
+        "PyPy doesn't support creation of generators from the C-API.")
+
+@slot_function([PyObject], lltype.Void)
+def gi_dealloc(space, py_obj):
+    _dealloc(space, py_obj)
diff --git a/pypy/module/cpyext/include/Python.h 
b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -127,6 +127,7 @@
 #include "pycapsule.h"
 #include "bytesobject.h"
 #include "sliceobject.h"
+#include "genobject.h"
 #include "datetime.h"
 #include "pystate.h"
 #include "fileobject.h"
diff --git a/pypy/module/cpyext/include/code.h 
b/pypy/module/cpyext/include/code.h
--- a/pypy/module/cpyext/include/code.h
+++ b/pypy/module/cpyext/include/code.h
@@ -20,6 +20,11 @@
 #define CO_VARKEYWORDS  0x0008
 #define CO_NESTED       0x0010
 #define CO_GENERATOR    0x0020
+  
+/* The CO_COROUTINE flag is set for coroutine functions (defined with
+   ``async def`` keywords) */
+#define CO_COROUTINE            0x0080
+#define CO_ITERABLE_COROUTINE   0x0100
 
 #define CO_FUTURE_DIVISION         0x02000
 #define CO_FUTURE_ABSOLUTE_IMPORT  0x04000
diff --git a/pypy/module/cpyext/include/genobject.h 
b/pypy/module/cpyext/include/genobject.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/genobject.h
@@ -0,0 +1,12 @@
+#ifndef Py_GENOBJECT_H
+#define Py_GENOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cpyext_genobject.h"
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_GENOBJECT_H */
diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py
--- a/pypy/module/cpyext/longobject.py
+++ b/pypy/module/cpyext/longobject.py
@@ -201,6 +201,10 @@
     for the conversion.  The radix must be in the range [2, 36]; if it is
     out of range, ValueError will be raised."""
     w_value = space.newunicode(rffi.wcharpsize2unicode(u, length))
+    return PyLong_FromUnicodeObject(space, w_value, base)
+
+@cpython_api([PyObject, rffi.INT_real], PyObject)
+def PyLong_FromUnicodeObject(space, w_value, base):
     w_base = space.newint(rffi.cast(lltype.Signed, base))
     return space.call_function(space.w_long, w_value, w_base)
 
diff --git a/pypy/module/cpyext/parse/cpyext_genobject.h 
b/pypy/module/cpyext/parse/cpyext_genobject.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/parse/cpyext_genobject.h
@@ -0,0 +1,4 @@
+typedef struct {
+    PyObject_HEAD
+    PyObject* gi_code;
+} PyGenObject;
diff --git a/pypy/module/cpyext/test/test_genobject.py 
b/pypy/module/cpyext/test/test_genobject.py
--- a/pypy/module/cpyext/test/test_genobject.py
+++ b/pypy/module/cpyext/test/test_genobject.py
@@ -28,7 +28,29 @@
         assert PyCoro_CheckExact(space, w_coroutine)
 
 class AppTestCoroutine(AppTestCpythonExtensionBase):
-    def test_simple(self):
+    def test_generator_coroutine(self):
+        module = self.import_extension('test_gen', [
+            ('is_coroutine', 'METH_O',
+             '''
+             if (!PyGen_CheckExact(args))
+                Py_RETURN_NONE;
+             PyObject* co = ((PyGenObject*)args)->gi_code;
+             if (((PyCodeObject*)co)->co_flags & CO_ITERABLE_COROUTINE)
+                Py_RETURN_TRUE;
+             else
+                Py_RETURN_FALSE;
+             ''')])
+
+        def it():
+            yield 42
+
+        print(module.is_coroutine(it()))
+        assert module.is_coroutine(it()) is False
+        self.debug_collect()  # don't crash while deallocating
+        from types import coroutine
+        assert module.is_coroutine(coroutine(it)()) is True
+
+    def test_await(self):
         """
         module = self.import_extension('test_coroutine', [
             ('await_', 'METH_O',
diff --git a/pypy/module/cpyext/test/test_longobject.py 
b/pypy/module/cpyext/test/test_longobject.py
--- a/pypy/module/cpyext/test/test_longobject.py
+++ b/pypy/module/cpyext/test/test_longobject.py
@@ -272,6 +272,19 @@
         # A string with arabic digits. 'BAD' is after the 6th character.
         assert module.from_unicode(u'  1\u0662\u0663\u0664BAD') == (1234, 4660)
 
+    def test_fromunicodeobject(self):
+        module = self.import_extension('foo', [
+            ("from_unicodeobject", "METH_O",
+             """
+                 return Py_BuildValue("NN",
+                     PyLong_FromUnicodeObject(args, 10),
+                     PyLong_FromUnicodeObject(args, 16));
+             """),
+            ])
+        # A string with arabic digits.
+        assert (module.from_unicodeobject(u'  1\u0662\u0663\u0664')
+                == (1234, 4660))
+
     def test_aslong(self):
         module = self.import_extension('foo', [
             ("as_long", "METH_O",
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py 
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -851,6 +851,17 @@
         assert r"['a\n', 'b\n', 'c\n', 'd']" == space.unwrap(space.repr(
                 PyUnicode_Splitlines(space, w_str, 1)))
 
+    def test_substring_api(self, space):
+        w_str = space.wrap(u"abcd")
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 1, 3)) == u"bc"
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 0, 4)) == u"abcd"
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 0, 9)) == u"abcd"
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 1, 4)) == u"bcd"
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 2, 2)) == u""
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 5, 4)) == u""
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 5, 3)) == u""
+        assert space.unwrap(PyUnicode_Substring(space, w_str, 4, 3)) == u""
+
     def test_Ready(self, space):
         w_str = space.wrap(u'abc')  # ASCII
         py_str = as_pyobj(space, w_str)
diff --git a/pypy/module/cpyext/unicodeobject.py 
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -1043,3 +1043,17 @@
     resulting strings."""
     w_keepend = space.newbool(bool(rffi.cast(lltype.Signed, keepend)))
     return space.call_method(w_str, "splitlines", w_keepend)
+
+@cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
+def PyUnicode_Substring(space, w_str, start, end):
+    usrc = space.unicode_w(w_str)
+    length = len(usrc)
+    if start < 0 or end < 0:
+        raise oefmt(space.w_IndexError, "string index out of range")
+    if start >= length or end < start:
+        result = u''
+    else:
+        if end > length:
+            end = length
+        result = usrc[start:end]
+    return space.newunicode(result)
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -348,7 +348,8 @@
                                  ('ifr_name', rffi.CFixedArray(rffi.CHAR, 8))])
 
 # insert handler for sendmsg / recvmsg here
-if _POSIX:
+HAVE_SENDMSG = bool(_POSIX)
+if HAVE_SENDMSG:
     includes = ['stddef.h',
                 'sys/socket.h',
                 'unistd.h',
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -1393,7 +1393,7 @@
         return (make_socket(fd0, family, type, proto, SocketClass),
                 make_socket(fd1, family, type, proto, SocketClass))
 
-if _c._POSIX:
+if _c.HAVE_SENDMSG:
     def CMSG_LEN( demanded_len):
         """
         Socket method to determine the optimal byte size of the ancillary.
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to