[pypy-commit] pypy py3.5-refactor-slots: hg merge py3.5

rlamy pypy.commits at gmail.com
Fri Jan 12 12:35:55 EST 2018


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5-refactor-slots
Changeset: r93659:be7fb656f9f4
Date: 2018-01-12 17:35 +0000
http://bitbucket.org/pypy/pypy/changeset/be7fb656f9f4/

Log:	hg merge py3.5

diff too long, truncating to 2000 out of 110564 lines

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -59,6 +59,7 @@
 ^rpython/rlib/rvmprof/src/shared/libbacktrace/config.h$
 ^rpython/rlib/rvmprof/src/shared/libbacktrace/config.log$
 ^rpython/rlib/rvmprof/src/shared/libbacktrace/config.status$
+^pypy/tool/dest$
 ^pypy/goal/pypy-translation-snapshot$
 ^pypy/goal/pypy-c
 ^pypy/goal/pypy3-c
@@ -75,6 +76,8 @@
 ^lib_pypy/.+.c$
 ^lib_pypy/.+.o$
 ^lib_pypy/.+.so$
+^lib_pypy/.+.pyd$
+^lib_pypy/Release/
 ^pypy/doc/discussion/.+\.html$
 ^include/.+\.h$
 ^include/.+\.inl$
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -40,3 +40,13 @@
 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1
 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0
 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0
+03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
+d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0
+03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
+84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0
+0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0
+a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0
+a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0
+0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0
+0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0
+09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -30,7 +30,7 @@
     DEALINGS IN THE SOFTWARE.
 
 
-PyPy Copyright holders 2003-2017
+PyPy Copyright holders 2003-2018
 ----------------------------------- 
 
 Except when otherwise stated (look for LICENSE files or information at
@@ -339,8 +339,10 @@
   Stanisław Halik
   Julien Phalip
   Roman Podoliaka
+  Steve Papanik
   Eli Stevens
   Boglarka Vezer
+  gabrielg
   PavloKapyshin
   Tomer Chachamu
   Christopher Groskopf
@@ -363,11 +365,13 @@
   Konrad Delong
   Dinu Gherman
   pizi
+  Tomáš Pružina
   James Robert
   Armin Ronacher
   Diana Popa
   Mads Kiilerich
   Brett Cannon
+  Caleb Hattingh
   aliceinwire
   Zooko Wilcox-O Hearn
   James Lan
@@ -388,6 +392,7 @@
   Jason Madden
   Yaroslav Fedevych
   Even Wiik Thomassen
+  m at funkyhat.org
   Stefan Marr
 
   Heinrich-Heine University, Germany 
diff --git a/_pytest/terminal.py b/_pytest/terminal.py
--- a/_pytest/terminal.py
+++ b/_pytest/terminal.py
@@ -366,11 +366,11 @@
             EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, EXIT_USAGEERROR,
             EXIT_NOTESTSCOLLECTED)
         if exitstatus in summary_exit_codes:
-            self.config.hook.pytest_terminal_summary(terminalreporter=self)
             self.summary_errors()
             self.summary_failures()
             self.summary_warnings()
             self.summary_passes()
+            self.config.hook.pytest_terminal_summary(terminalreporter=self)
         if exitstatus == EXIT_INTERRUPTED:
             self._report_keyboardinterrupt()
             del self._keyboardinterrupt_memo
diff --git a/extra_tests/requirements.txt b/extra_tests/requirements.txt
new file mode 100644
--- /dev/null
+++ b/extra_tests/requirements.txt
@@ -0,0 +1,3 @@
+pytest
+hypothesis
+vmprof
diff --git a/extra_tests/test_bytes.py b/extra_tests/test_bytes.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_bytes.py
@@ -0,0 +1,84 @@
+from hypothesis import strategies as st
+from hypothesis import given, example
+
+st_bytestring = st.binary() | st.binary().map(bytearray)
+
+ at given(st_bytestring, st_bytestring, st_bytestring)
+def test_find(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert 0 <= s.find(u) <= len(prefix)
+    assert s.find(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st_bytestring, st_bytestring, st_bytestring)
+def test_index(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert 0 <= s.index(u) <= len(prefix)
+    assert s.index(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st_bytestring, st_bytestring, st_bytestring)
+def test_rfind(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert s.rfind(u) >= len(prefix)
+    assert s.rfind(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st_bytestring, st_bytestring, st_bytestring)
+def test_rindex(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert s.rindex(u) >= len(prefix)
+    assert s.rindex(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+def adjust_indices(u, start, end):
+    if end < 0:
+        end = max(end + len(u), 0)
+    else:
+        end = min(end, len(u))
+    if start < 0:
+        start = max(start + len(u), 0)
+    return start, end
+
+ at given(st_bytestring, st_bytestring)
+def test_startswith_basic(u, v):
+    assert u.startswith(v) is (u[:len(v)] == v)
+
+ at example(b'x', b'', 1)
+ at example(b'x', b'', 2)
+ at given(st_bytestring, st_bytestring, st.integers())
+def test_startswith_start(u, v, start):
+    expected = u[start:].startswith(v) if v else (start <= len(u))
+    assert u.startswith(v, start) is expected
+
+ at example(b'x', b'', 1, 0)
+ at example(b'xx', b'', -1, 0)
+ at given(st_bytestring, st_bytestring, st.integers(), st.integers())
+def test_startswith_3(u, v, start, end):
+    if v:
+        expected = u[start:end].startswith(v)
+    else:  # CPython leaks implementation details in this case
+        start0, end0 = adjust_indices(u, start, end)
+        expected = start0 <= len(u) and start0 <= end0
+    assert u.startswith(v, start, end) is expected
+
+ at given(st_bytestring, st_bytestring)
+def test_endswith_basic(u, v):
+    if len(v) > len(u):
+        assert u.endswith(v) is False
+    else:
+        assert u.endswith(v) is (u[len(u) - len(v):] == v)
+
+ at example(b'x', b'', 1)
+ at example(b'x', b'', 2)
+ at given(st_bytestring, st_bytestring, st.integers())
+def test_endswith_2(u, v, start):
+    expected = u[start:].endswith(v) if v else (start <= len(u))
+    assert u.endswith(v, start) is expected
+
+ at example(b'x', b'', 1, 0)
+ at example(b'xx', b'', -1, 0)
+ at given(st_bytestring, st_bytestring, st.integers(), st.integers())
+def test_endswith_3(u, v, start, end):
+    if v:
+        expected = u[start:end].endswith(v)
+    else:  # CPython leaks implementation details in this case
+        start0, end0 = adjust_indices(u, start, end)
+        expected = start0 <= len(u) and start0 <= end0
+    assert u.endswith(v, start, end) is expected
diff --git a/extra_tests/test_import.py b/extra_tests/test_import.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_import.py
@@ -0,0 +1,41 @@
+import pytest
+import sys
+import time
+from _thread import start_new_thread
+
+ at pytest.mark.xfail('__pypy__' not in sys.builtin_module_names,
+                   reason='Fails on CPython')
+def test_multithreaded_import(tmpdir):
+    tmpfile = tmpdir.join('multithreaded_import_test.py')
+    tmpfile.write('''if 1:
+        x = 666
+        import time
+        for i in range(1000): time.sleep(0.001)
+        x = 42
+    ''')
+
+    oldpath = sys.path[:]
+    try:
+        sys.path.insert(0, str(tmpdir))
+        got = []
+
+        def check():
+            import multithreaded_import_test
+            got.append(getattr(multithreaded_import_test, 'x', '?'))
+
+        for i in range(5):
+            start_new_thread(check, ())
+
+        for n in range(100):
+            for i in range(105):
+                time.sleep(0.001)
+            if len(got) == 5:
+                break
+        else:
+            raise AssertionError("got %r so far but still waiting" %
+                                    (got,))
+
+        assert got == [42] * 5
+
+    finally:
+        sys.path[:] = oldpath
diff --git a/extra_tests/test_json.py b/extra_tests/test_json.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_json.py
@@ -0,0 +1,29 @@
+import pytest
+import json
+from hypothesis import given, strategies
+
+def is_(x, y):
+    return type(x) is type(y) and x == y
+
+def test_no_ensure_ascii():
+    assert is_(json.dumps(u"\u1234", ensure_ascii=False), u'"\u1234"')
+    assert is_(json.dumps(u"\xc0", ensure_ascii=False), u'"\xc0"')
+    with pytest.raises(TypeError):
+        json.dumps((u"\u1234", b"x"), ensure_ascii=False)
+    with pytest.raises(TypeError):
+        json.dumps((b"x", u"\u1234"), ensure_ascii=False)
+
+def test_issue2191():
+    assert is_(json.dumps(u"xxx", ensure_ascii=False), u'"xxx"')
+
+jsondata = strategies.recursive(
+    strategies.none() |
+    strategies.booleans() |
+    strategies.floats(allow_nan=False) |
+    strategies.text(),
+    lambda children: strategies.lists(children) |
+        strategies.dictionaries(strategies.text(), children))
+
+ at given(jsondata)
+def test_roundtrip(d):
+    assert json.loads(json.dumps(d)) == d
diff --git a/extra_tests/test_textio.py b/extra_tests/test_textio.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_textio.py
@@ -0,0 +1,48 @@
+from hypothesis import given, strategies as st
+
+from io import BytesIO, TextIOWrapper
+import os
+
+def translate_newlines(text):
+    text = text.replace('\r\n', '\n')
+    text = text.replace('\r', '\n')
+    return text.replace('\n', os.linesep)
+
+ at st.composite
+def st_readline_universal(
+        draw, st_nlines=st.integers(min_value=0, max_value=10)):
+    n_lines = draw(st_nlines)
+    lines = draw(st.lists(
+        st.text(st.characters(blacklist_characters='\r\n')),
+        min_size=n_lines, max_size=n_lines))
+    limits = []
+    for line in lines:
+        limit = draw(st.integers(min_value=0, max_value=len(line) + 5))
+        limits.append(limit)
+        limits.append(-1)
+    endings = draw(st.lists(
+        st.sampled_from(['\n', '\r', '\r\n']),
+        min_size=n_lines, max_size=n_lines))
+    return (
+        ''.join(line + ending for line, ending in zip(lines, endings)),
+        limits)
+
+ at given(data=st_readline_universal(),
+       mode=st.sampled_from(['\r', '\n', '\r\n', '', None]))
+def test_readline(data, mode):
+    txt, limits = data
+    textio = TextIOWrapper(
+        BytesIO(txt.encode('utf-8', 'surrogatepass')),
+        encoding='utf-8', errors='surrogatepass', newline=mode)
+    lines = []
+    for limit in limits:
+        line = textio.readline(limit)
+        if limit >= 0:
+            assert len(line) <= limit
+        if line:
+            lines.append(line)
+        elif limit:
+            break
+    if mode is None:
+        txt = translate_newlines(txt)
+    assert txt.startswith(u''.join(lines))
diff --git a/extra_tests/test_unicode.py b/extra_tests/test_unicode.py
--- a/extra_tests/test_unicode.py
+++ b/extra_tests/test_unicode.py
@@ -1,3 +1,4 @@
+import sys
 import pytest
 from hypothesis import strategies as st
 from hypothesis import given, settings, example
@@ -32,3 +33,89 @@
 @given(s=st.text())
 def test_composition(s, norm1, norm2, norm3):
     assert normalize(norm2, normalize(norm1, s)) == normalize(norm3, s)
+
+ at given(st.text(), st.text(), st.text())
+def test_find(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert 0 <= s.find(u) <= len(prefix)
+    assert s.find(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st.text(), st.text(), st.text())
+def test_index(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert 0 <= s.index(u) <= len(prefix)
+    assert s.index(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st.text(), st.text(), st.text())
+def test_rfind(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert s.rfind(u) >= len(prefix)
+    assert s.rfind(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+ at given(st.text(), st.text(), st.text())
+def test_rindex(u, prefix, suffix):
+    s = prefix + u + suffix
+    assert s.rindex(u) >= len(prefix)
+    assert s.rindex(u, len(prefix), len(s) - len(suffix)) == len(prefix)
+
+def adjust_indices(u, start, end):
+    if end < 0:
+        end = max(end + len(u), 0)
+    else:
+        end = min(end, len(u))
+    if start < 0:
+        start = max(start + len(u), 0)
+    return start, end
+
+ at given(st.text(), st.text())
+def test_startswith_basic(u, v):
+    assert u.startswith(v) is (u[:len(v)] == v)
+
+ at example(u'x', u'', 1)
+ at example(u'x', u'', 2)
+ at given(st.text(), st.text(), st.integers())
+def test_startswith_2(u, v, start):
+    if v or sys.version_info[0] == 2:
+        expected = u[start:].startswith(v)
+    else:  # CPython leaks implementation details in this case
+        expected = start <= len(u)
+    assert u.startswith(v, start) is expected
+
+ at example(u'x', u'', 1, 0)
+ at example(u'xx', u'', -1, 0)
+ at given(st.text(), st.text(), st.integers(), st.integers())
+def test_startswith_3(u, v, start, end):
+    if v or sys.version_info[0] == 2:
+        expected = u[start:end].startswith(v)
+    else:  # CPython leaks implementation details in this case
+        start0, end0 = adjust_indices(u, start, end)
+        expected = start0 <= len(u) and start0 <= end0
+    assert u.startswith(v, start, end) is expected
+
+ at given(st.text(), st.text())
+def test_endswith_basic(u, v):
+    if len(v) > len(u):
+        assert u.endswith(v) is False
+    else:
+        assert u.endswith(v) is (u[len(u) - len(v):] == v)
+
+ at example(u'x', u'', 1)
+ at example(u'x', u'', 2)
+ at given(st.text(), st.text(), st.integers())
+def test_endswith_2(u, v, start):
+    if v or sys.version_info[0] == 2:
+        expected = u[start:].endswith(v)
+    else:  # CPython leaks implementation details in this case
+        expected = start <= len(u)
+    assert u.endswith(v, start) is expected
+
+ at example(u'x', u'', 1, 0)
+ at example(u'xx', u'', -1, 0)
+ at given(st.text(), st.text(), st.integers(), st.integers())
+def test_endswith_3(u, v, start, end):
+    if v or sys.version_info[0] == 2:
+        expected = u[start:end].endswith(v)
+    else:  # CPython leaks implementation details in this case
+        start0, end0 = adjust_indices(u, start, end)
+        expected = start0 <= len(u) and start0 <= end0
+    assert u.endswith(v, start, end) is expected
diff --git a/extra_tests/test_vmprof_greenlet.py b/extra_tests/test_vmprof_greenlet.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_vmprof_greenlet.py
@@ -0,0 +1,28 @@
+import time
+import pytest
+import greenlet
+vmprof = pytest.importorskip('vmprof')
+
+def count_samples(filename):
+    stats = vmprof.read_profile(filename)
+    return len(stats.profiles)
+
+def cpuburn(duration):
+    end = time.time() + duration
+    while time.time() < end:
+        pass
+
+def test_sampling_inside_callback(tmpdir):
+    # see also test_sampling_inside_callback inside
+    # pypy/module/_continuation/test/test_stacklet.py
+    #
+    G = greenlet.greenlet(cpuburn)
+    fname = tmpdir.join('log.vmprof')
+    with fname.open('w+b') as f:
+        vmprof.enable(f.fileno(), 1/250.0)
+        G.switch(0.1)
+        vmprof.disable()
+    
+    samples = count_samples(str(fname))
+    # 0.1 seconds at 250Hz should be 25 samples
+    assert 23 < samples < 27
diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -360,14 +360,15 @@
         self._FuncPtr = _FuncPtr
 
         if handle is None:
-            if flags & _FUNCFLAG_CDECL:
-                pypy_dll = _ffi.CDLL(name, mode)
-            else:
-                pypy_dll = _ffi.WinDLL(name, mode)
-            self.__pypy_dll__ = pypy_dll
-            handle = int(pypy_dll)
-            if _sys.maxint > 2 ** 32:
-                handle = int(handle)   # long -> int
+            handle = 0
+        if flags & _FUNCFLAG_CDECL:
+            pypy_dll = _ffi.CDLL(name, mode, handle)
+        else:
+            pypy_dll = _ffi.WinDLL(name, mode, handle)
+        self.__pypy_dll__ = pypy_dll
+        handle = int(pypy_dll)
+        if _sys.maxint > 2 ** 32:
+            handle = int(handle)   # long -> int
         self._handle = handle
 
     def __repr__(self):
diff --git a/lib-python/2.7/inspect.py b/lib-python/2.7/inspect.py
--- a/lib-python/2.7/inspect.py
+++ b/lib-python/2.7/inspect.py
@@ -40,6 +40,10 @@
 import linecache
 from operator import attrgetter
 from collections import namedtuple
+try:
+    from cpyext import is_cpyext_function as _is_cpyext_function
+except ImportError:
+    _is_cpyext_function = lambda obj: False
 
 # These constants are from Include/code.h.
 CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8
@@ -230,7 +234,7 @@
         __doc__         documentation string
         __name__        original name of this function or method
         __self__        instance to which a method is bound, or None"""
-    return isinstance(object, types.BuiltinFunctionType)
+    return isinstance(object, types.BuiltinFunctionType) or _is_cpyext_function(object)
 
 def isroutine(object):
     """Return true if the object is any kind of function or method."""
diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py
--- a/lib-python/2.7/subprocess.py
+++ b/lib-python/2.7/subprocess.py
@@ -1296,7 +1296,7 @@
                   'copyfile' in caller.f_globals):
         dest_dir = sys.pypy_resolvedirof(target_executable)
         src_dir = sys.pypy_resolvedirof(sys.executable)
-        for libname in ['libpypy-c.so', 'libpypy-c.dylib']:
+        for libname in ['libpypy-c.so', 'libpypy-c.dylib', 'libpypy-c.dll']:
             dest_library = os.path.join(dest_dir, libname)
             src_library = os.path.join(src_dir, libname)
             if os.path.exists(src_library):
diff --git a/lib-python/2.7/test/test_urllib2net.py b/lib-python/2.7/test/test_urllib2net.py
--- a/lib-python/2.7/test/test_urllib2net.py
+++ b/lib-python/2.7/test/test_urllib2net.py
@@ -286,7 +286,7 @@
             self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 120)
             u.close()
 
-    FTP_HOST = 'ftp://ftp.debian.org/debian/'
+    FTP_HOST = 'ftp://www.pythontest.net/'
 
     def test_ftp_basic(self):
         self.assertIsNone(socket.getdefaulttimeout())
diff --git a/lib-python/2.7/warnings.py b/lib-python/2.7/warnings.py
--- a/lib-python/2.7/warnings.py
+++ b/lib-python/2.7/warnings.py
@@ -43,11 +43,12 @@
         unicodetype = unicode
     except NameError:
         unicodetype = ()
+    template = "%s: %s: %s\n"
     try:
         message = str(message)
     except UnicodeEncodeError:
-        pass
-    s =  "%s: %s: %s\n" % (lineno, category.__name__, message)
+        template = unicode(template)
+    s = template % (lineno, category.__name__, message)
     line = linecache.getline(filename, lineno) if line is None else line
     if line:
         line = line.strip()
diff --git a/lib-python/3/ctypes/test/test_bitfields.py b/lib-python/3/ctypes/test/test_bitfields.py
--- a/lib-python/3/ctypes/test/test_bitfields.py
+++ b/lib-python/3/ctypes/test/test_bitfields.py
@@ -1,5 +1,5 @@
 from ctypes import *
-from ctypes.test import need_symbol
+from ctypes.test import need_symbol, xfail
 import unittest
 import os
 
@@ -279,6 +279,7 @@
         self.assertEqual(b, b'\xef\xcd\xab\x21')
 
     @need_symbol('c_uint32')
+    @xfail
     def test_uint32_swap_big_endian(self):
         # Issue #23319
         class Big(BigEndianStructure):
diff --git a/lib-python/3/ctypes/test/test_byteswap.py b/lib-python/3/ctypes/test/test_byteswap.py
--- a/lib-python/3/ctypes/test/test_byteswap.py
+++ b/lib-python/3/ctypes/test/test_byteswap.py
@@ -2,6 +2,7 @@
 from binascii import hexlify
 
 from ctypes import *
+from test.support import impl_detail
 
 def bin(s):
     return hexlify(memoryview(s)).decode().upper()
@@ -22,6 +23,7 @@
             setattr(bits, "i%s" % i, 1)
             dump(bits)
 
+    @impl_detail("slots are irrelevant on PyPy", pypy=False)
     def test_slots(self):
         class BigPoint(BigEndianStructure):
             __slots__ = ()
diff --git a/lib-python/3/ctypes/test/test_frombuffer.py b/lib-python/3/ctypes/test/test_frombuffer.py
--- a/lib-python/3/ctypes/test/test_frombuffer.py
+++ b/lib-python/3/ctypes/test/test_frombuffer.py
@@ -85,7 +85,6 @@
         del a
         gc.collect()  # Should not crash
 
-    @xfail
     def test_from_buffer_copy(self):
         a = array.array("i", range(16))
         x = (c_int * 16).from_buffer_copy(a)
diff --git a/lib-python/3/ctypes/test/test_values.py b/lib-python/3/ctypes/test/test_values.py
--- a/lib-python/3/ctypes/test/test_values.py
+++ b/lib-python/3/ctypes/test/test_values.py
@@ -4,6 +4,7 @@
 
 import unittest
 import sys
+from test.support import cpython_only
 from ctypes import *
 
 import _ctypes_test
@@ -28,6 +29,7 @@
         ctdll = CDLL(_ctypes_test.__file__)
         self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
 
+ at cpython_only
 class PythonValuesTestCase(unittest.TestCase):
     """This test only works when python itself is a dll/shared library"""
 
diff --git a/lib-python/3/doctest.py b/lib-python/3/doctest.py
--- a/lib-python/3/doctest.py
+++ b/lib-python/3/doctest.py
@@ -939,6 +939,8 @@
         elif inspect.getmodule(object) is not None:
             return module is inspect.getmodule(object)
         elif inspect.isfunction(object):
+            if isinstance(object.__code__, inspect._builtin_code_type):
+                return True  # XXX: A PyPy builtin - no way to tell
             return module.__dict__ is object.__globals__
         elif inspect.ismethoddescriptor(object):
             if hasattr(object, '__objclass__'):
diff --git a/lib-python/3/idlelib/CallTips.py b/lib-python/3/idlelib/CallTips.py
--- a/lib-python/3/idlelib/CallTips.py
+++ b/lib-python/3/idlelib/CallTips.py
@@ -123,6 +123,15 @@
 _first_param = re.compile('(?<=\()\w*\,?\s*')
 _default_callable_argspec = "See source or doc"
 
+def _is_user_method(ob):
+    """Detect user methods on PyPy"""
+    return (isinstance(ob, types.MethodType) and
+        isinstance(ob.__code__, types.CodeType))
+
+def _is_user_function(ob):
+    """Detect user methods on PyPy"""
+    return (isinstance(ob, types.FunctionType) and
+        isinstance(ob.__code__, types.CodeType))
 
 def get_argspec(ob):
     '''Return a string describing the signature of a callable object, or ''.
@@ -140,21 +149,21 @@
         return argspec
     if isinstance(ob, type):
         fob = ob.__init__
-    elif isinstance(ob_call, types.MethodType):
+    elif _is_user_method(ob_call):
         fob = ob_call
     else:
         fob = ob
     if (isinstance(fob, (types.FunctionType, types.MethodType)) and
             hasattr(fob.__code__, 'co_code')):  # PyPy: not on <builtin-code>
         argspec = inspect.formatargspec(*inspect.getfullargspec(fob))
-        if (isinstance(ob, (type, types.MethodType)) or
-                isinstance(ob_call, types.MethodType)):
+        if (_is_user_method(ob) or _is_user_method(ob_call) or
+                (isinstance(ob, type) and _is_user_function(fob))):
             argspec = _first_param.sub("", argspec)
 
     lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT)
             if len(argspec) > _MAX_COLS else [argspec] if argspec else [])
 
-    if isinstance(ob_call, types.MethodType):
+    if _is_user_method(ob_call):
         doc = ob_call.__doc__
     else:
         doc = getattr(ob, "__doc__", "")
diff --git a/lib-python/3/idlelib/idle_test/test_calltips.py b/lib-python/3/idlelib/idle_test/test_calltips.py
--- a/lib-python/3/idlelib/idle_test/test_calltips.py
+++ b/lib-python/3/idlelib/idle_test/test_calltips.py
@@ -63,7 +63,7 @@
         gtest([].append, append_doc)
         gtest(List.append, append_doc)
 
-        gtest(types.MethodType, "method(function, instance)")
+        gtest(types.MethodType, "instancemethod(function, instance, class)")
         gtest(SB(), default_tip)
 
     def test_signature_wrap(self):
diff --git a/lib-python/3/inspect.py b/lib-python/3/inspect.py
--- a/lib-python/3/inspect.py
+++ b/lib-python/3/inspect.py
@@ -49,6 +49,10 @@
 import builtins
 from operator import attrgetter
 from collections import namedtuple, OrderedDict
+try:
+    from cpyext import is_cpyext_function as _is_cpyext_function
+except ImportError:
+    _is_cpyext_function = lambda obj: False
 
 # Create constants for the compiler flags in Include/code.h
 # We try to get them from dis to avoid duplication
@@ -262,7 +266,7 @@
         __doc__         documentation string
         __name__        original name of this function or method
         __self__        instance to which a method is bound, or None"""
-    return isinstance(object, types.BuiltinFunctionType)
+    return isinstance(object, types.BuiltinFunctionType) or _is_cpyext_function(object)
 
 def isroutine(object):
     """Return true if the object is any kind of function or method."""
@@ -1824,7 +1828,7 @@
     kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
     annotations = getattr(obj, '__annotations__', None)
 
-    return (isinstance(code, types.CodeType) and
+    return (isinstance(code, (types.CodeType, _builtin_code_type)) and
             isinstance(name, str) and
             (defaults is None or isinstance(defaults, tuple)) and
             (kwdefaults is None or isinstance(kwdefaults, dict)) and
@@ -2078,8 +2082,6 @@
 
     s = getattr(func, "__text_signature__", None)
     if not s:
-        if func is object:  # XXX PyPy hack until we support __text_signature__
-            return '()'     # in the same cases as CPython
         raise ValueError("no signature found for builtin {!r}".format(func))
 
     return _signature_fromstr(cls, func, s, skip_bound_arg)
diff --git a/lib-python/3/subprocess.py b/lib-python/3/subprocess.py
--- a/lib-python/3/subprocess.py
+++ b/lib-python/3/subprocess.py
@@ -1560,7 +1560,7 @@
                   'copyfile' in caller.f_globals):
         dest_dir = sys.pypy_resolvedirof(target_executable)
         src_dir = sys.pypy_resolvedirof(sys.executable)
-        for libname in ['libpypy3-c.so', 'libpypy3-c.dylib']:
+        for libname in ['libpypy3-c.so', 'libpypy3-c.dylib', 'libpypy3-c.dll']:
             dest_library = os.path.join(dest_dir, libname)
             src_library = os.path.join(src_dir, libname)
             if os.path.exists(src_library):
diff --git a/lib-python/3/test/test_bytes.py b/lib-python/3/test/test_bytes.py
--- a/lib-python/3/test/test_bytes.py
+++ b/lib-python/3/test/test_bytes.py
@@ -721,9 +721,12 @@
         self.assertIs(type(BytesSubclass(A())), BytesSubclass)
 
     # Test PyBytes_FromFormat()
-    @test.support.impl_detail("don't test cpyext here")
     def test_from_format(self):
         test.support.import_module('ctypes')
+        try:
+            from ctypes import pythonapi
+        except ImportError:
+            self.skipTest( "no pythonapi in ctypes")
         from ctypes import pythonapi, py_object, c_int, c_char_p
         PyBytes_FromFormat = pythonapi.PyBytes_FromFormat
         PyBytes_FromFormat.restype = py_object
diff --git a/lib-python/3/test/test_capi.py b/lib-python/3/test/test_capi.py
--- a/lib-python/3/test/test_capi.py
+++ b/lib-python/3/test/test_capi.py
@@ -29,8 +29,9 @@
 skips = []
 if support.check_impl_detail(pypy=True):
     skips += [
-            'test_widechar',
-            ]
+        'test_lazy_hash_inheritance',
+        'test_capsule',
+    ]
 
 def testfunction(self):
     """some doc"""
@@ -53,6 +54,8 @@
         self.assertEqual(testfunction.attribute, "test")
         self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test")
 
+    @unittest.skipIf(support.check_impl_detail(pypy=True),
+                    "doesn't crash on PyPy")
     @unittest.skipUnless(threading, 'Threading required for this test.')
     def test_no_FatalError_infinite_loop(self):
         with support.SuppressCrashReport():
@@ -205,9 +208,9 @@
         else:
             with self.assertRaises(SystemError) as cm:
                 _testcapi.return_null_without_error()
+            # PyPy change: different message
             self.assertRegex(str(cm.exception),
-                             'return_null_without_error.* '
-                             'returned NULL without setting an error')
+                'Function returned a NULL result without setting an exception')
 
     def test_return_result_with_error(self):
         # Issue #23571: A function must not return a result with an error set
@@ -237,9 +240,9 @@
         else:
             with self.assertRaises(SystemError) as cm:
                 _testcapi.return_result_with_error()
+            # PyPy change: different message
             self.assertRegex(str(cm.exception),
-                             'return_result_with_error.* '
-                             'returned a result with an error set')
+                'An exception was set, but function returned a value')
 
     def test_buildvalue_N(self):
         _testcapi.test_buildvalue_N()
@@ -327,6 +330,8 @@
         self.pendingcalls_wait(l, n)
 
 
+ at unittest.skipIf(support.check_impl_detail(pypy=True),
+                "subinterpreters not implemented on PyPy")
 class SubinterpreterTest(unittest.TestCase):
 
     def test_subinterps(self):
diff --git a/lib-python/3/test/test_cmd_line_script.py b/lib-python/3/test/test_cmd_line_script.py
--- a/lib-python/3/test/test_cmd_line_script.py
+++ b/lib-python/3/test/test_cmd_line_script.py
@@ -43,11 +43,7 @@
 _loader = __loader__ if __loader__ is BuiltinImporter else type(__loader__)
 print('__loader__==%a' % _loader)
 print('__file__==%a' % __file__)
-if __cached__ is not None:
-    # XXX: test_script_compiled on PyPy
-    assertEqual(__file__, __cached__)
-    if not __cached__.endswith(('pyc', 'pyo')):
-        raise AssertionError('has __cached__ but not compiled')
+print('__cached__==%a' % __cached__)
 print('__package__==%r' % __package__)
 # Check PEP 451 details
 import os.path
@@ -239,9 +235,8 @@
     def test_basic_script(self):
         with support.temp_dir() as script_dir:
             script_name = _make_test_script(script_dir, 'script')
-            package = '' if support.check_impl_detail(pypy=True) else None
             self._check_script(script_name, script_name, script_name,
-                               script_dir, package,
+                               script_dir, None,
                                importlib.machinery.SourceFileLoader)
 
     def test_script_compiled(self):
@@ -250,9 +245,8 @@
             py_compile.compile(script_name, doraise=True)
             os.remove(script_name)
             pyc_file = support.make_legacy_pyc(script_name)
-            package = '' if support.check_impl_detail(pypy=True) else None
             self._check_script(pyc_file, pyc_file,
-                               pyc_file, script_dir, package,
+                               pyc_file, script_dir, None,
                                importlib.machinery.SourcelessFileLoader)
 
     def test_directory(self):
diff --git a/lib-python/3/test/test_compile.py b/lib-python/3/test/test_compile.py
--- a/lib-python/3/test/test_compile.py
+++ b/lib-python/3/test/test_compile.py
@@ -524,7 +524,8 @@
             with open(fn, "wb") as fp:
                 fp.write(src)
             res = script_helper.run_python_until_end(fn)[0]
-        self.assertIn(b"Non-UTF-8", res.err)
+        # PyPy change: we have a different error here
+        self.assertIn(b"SyntaxError", res.err)
 
     def test_yet_more_evil_still_undecodable(self):
         # Issue #25388
diff --git a/lib-python/3/test/test_cprofile.py b/lib-python/3/test/test_cprofile.py
--- a/lib-python/3/test/test_cprofile.py
+++ b/lib-python/3/test/test_cprofile.py
@@ -1,7 +1,7 @@
 """Test suite for the cProfile module."""
 
 import sys
-from test.support import run_unittest, TESTFN, unlink
+from test.support import run_unittest, TESTFN, unlink, cpython_only
 
 # rip off all interesting stuff from test_profile
 import cProfile
@@ -16,6 +16,7 @@
         return _ProfileOutput
 
     # Issue 3895.
+    @cpython_only
     def test_bad_counter_during_dealloc(self):
         import _lsprof
         # Must use a file as StringIO doesn't trigger the bug.
diff --git a/lib-python/3/test/test_descr.py b/lib-python/3/test/test_descr.py
--- a/lib-python/3/test/test_descr.py
+++ b/lib-python/3/test/test_descr.py
@@ -4278,7 +4278,10 @@
         c = C()
         c.__dict__[Evil()] = 0
 
-        self.assertEqual(c.attr, 1)
+        try:
+            self.assertEqual(c.attr, 1)
+        except AttributeError:  # when Evil.__eq__ is called twice
+            pass
         # this makes a crash more likely:
         support.gc_collect()
         self.assertNotHasAttr(c, 'attr')
diff --git a/lib-python/3/test/test_dis.py b/lib-python/3/test/test_dis.py
--- a/lib-python/3/test/test_dis.py
+++ b/lib-python/3/test/test_dis.py
@@ -146,24 +146,26 @@
               1)
     pass
 
+# PyPy change: JUMP_IF_NOT_DEBUG
 dis_bug1333982 = """\
-%3d           0 LOAD_CONST               1 (0)
-              3 POP_JUMP_IF_TRUE        35
-              6 LOAD_GLOBAL              0 (AssertionError)
-              9 LOAD_CONST               2 (<code object <listcomp> at 0x..., file "%s", line %d>)
-             12 LOAD_CONST               3 ('bug1333982.<locals>.<listcomp>')
-             15 MAKE_FUNCTION            0
-             18 LOAD_FAST                0 (x)
-             21 GET_ITER
-             22 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
+%3d           0 JUMP_IF_NOT_DEBUG       35 (to 38)
+              3 LOAD_CONST               1 (0)
+              6 POP_JUMP_IF_TRUE        38
+              9 LOAD_GLOBAL              0 (AssertionError)
+             12 LOAD_CONST               2 (<code object <listcomp> at 0x..., file "%s", line %d>)
+             15 LOAD_CONST               3 ('bug1333982.<locals>.<listcomp>')
+             18 MAKE_FUNCTION            0
+             21 LOAD_FAST                0 (x)
+             24 GET_ITER
+             25 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
 
-%3d          25 LOAD_CONST               4 (1)
-             28 BINARY_ADD
-             29 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
-             32 RAISE_VARARGS            1
+%3d          28 LOAD_CONST               4 (1)
+             31 BINARY_ADD
+             32 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
+             35 RAISE_VARARGS            1
 
-%3d     >>   35 LOAD_CONST               0 (None)
-             38 RETURN_VALUE
+%3d     >>   38 LOAD_CONST               0 (None)
+             41 RETURN_VALUE
 """ % (bug1333982.__code__.co_firstlineno + 1,
        __file__,
        bug1333982.__code__.co_firstlineno + 1,
diff --git a/lib-python/3/test/test_doctest.py b/lib-python/3/test/test_doctest.py
--- a/lib-python/3/test/test_doctest.py
+++ b/lib-python/3/test/test_doctest.py
@@ -660,7 +660,7 @@
 
     >>> import builtins
     >>> tests = doctest.DocTestFinder().find(builtins)
-    >>> lo, hi = (120, 140) if is_pypy else (790, 810)
+    >>> lo, hi = (420, 440) if is_pypy else (790, 810)
     >>> lo < len(tests) < hi # approximate number of objects with docstrings
     True
     >>> real_tests = [t for t in tests if len(t.examples) > 0]
diff --git a/lib-python/3/test/test_inspect.py b/lib-python/3/test/test_inspect.py
--- a/lib-python/3/test/test_inspect.py
+++ b/lib-python/3/test/test_inspect.py
@@ -32,6 +32,8 @@
 from test.support import check_impl_detail
 
 from test.test_import import _ready_to_import
+if check_impl_detail():
+    import _pickle
 
 
 # Functions tested in this suite:
@@ -362,6 +364,7 @@
         self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
                          'The automatic gainsaying.')
 
+    @cpython_only  # XXX: _finddoc() is broken on PyPy, but getdoc() seems OK
     @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
     def test_finddoc(self):
         finddoc = inspect._finddoc
@@ -755,21 +758,23 @@
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_getfullargspec_builtin_methods(self):
-        import _pickle
-        self.assertFullArgSpecEquals(_pickle.Pickler.dump,
-                                     args_e=['self', 'obj'], formatted='(self, obj)')
-
-        self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
-                                     args_e=['self', 'obj'], formatted='(self, obj)')
+        if check_impl_detail():
+            self.assertFullArgSpecEquals(_pickle.Pickler.dump,
+                                        args_e=['self', 'obj'], formatted='(self, obj)')
+
+            self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump,
+                                        args_e=['self', 'obj'], formatted='(self, obj)')
+
+        # platform-dependent on PyPy
+        default_fd = os.stat.__kwdefaults__['dir_fd']
 
         self.assertFullArgSpecEquals(
              os.stat,
              args_e=['path'],
              kwonlyargs_e=['dir_fd', 'follow_symlinks'],
-             kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
-             formatted='(path, *, dir_fd=None, follow_symlinks=True)')
-
-    @cpython_only
+             kwonlydefaults_e={'dir_fd': default_fd, 'follow_symlinks': True},
+             formatted='(path, *, dir_fd={}, follow_symlinks=True)'.format(default_fd))
+
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_getfullagrspec_builtin_func(self):
@@ -778,7 +783,6 @@
         spec = inspect.getfullargspec(builtin)
         self.assertEqual(spec.defaults[0], 'avocado')
 
-    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_getfullagrspec_builtin_func_no_signature(self):
@@ -816,7 +820,9 @@
 
         attrs = attrs_wo_objs(A)
 
-        self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
+        # changed in PyPy
+        self.assertIn(('__new__', 'static method', object), attrs, 'missing __new__')
+
         self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
 
         self.assertIn(('s', 'static method', A), attrs, 'missing static method')
@@ -1959,12 +1965,10 @@
                            ('kwargs', ..., int, "var_keyword")),
                           ...))
 
-    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_signature_on_builtins(self):
         import _testcapi
-        import _pickle
 
         def test_unbound_method(o):
             """Use this to test unbound methods (things that should have a self)"""
@@ -1998,9 +2002,10 @@
 
         # normal method
         # (PyMethodDescr_Type, "method_descriptor")
-        test_unbound_method(_pickle.Pickler.dump)
-        d = _pickle.Pickler(io.StringIO())
-        test_callable(d.dump)
+        if check_impl_detail():
+            test_unbound_method(_pickle.Pickler.dump)
+            d = _pickle.Pickler(io.StringIO())
+            test_callable(d.dump)
 
         # static method
         test_callable(str.maketrans)
@@ -2021,7 +2026,7 @@
 
         # This doesn't work now.
         # (We don't have a valid signature for "type" in 3.4)
-        with self.assertRaisesRegex(ValueError, "no signature found"):
+        with self.assertRaisesRegex(ValueError, "signature"):
             class ThisWorksNow:
                 __call__ = type
             test_callable(ThisWorksNow())
@@ -2033,7 +2038,6 @@
         # Regression test for issue #20586
         test_callable(_testcapi.docstring_with_signature_but_no_doc)
 
-    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_signature_on_decorated_builtins(self):
@@ -2056,7 +2060,6 @@
                                            follow_wrapped=False),
                          inspect.signature(wrapper_like))
 
-    @cpython_only
     def test_signature_on_builtins_no_signature(self):
         import _testcapi
         with self.assertRaisesRegex(ValueError,
@@ -2632,10 +2635,10 @@
         with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
             self.assertEqual(inspect.signature(D), None)
 
+    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_signature_on_builtin_class(self):
-        import _pickle
         self.assertEqual(str(inspect.signature(_pickle.Pickler)),
                          '(file, protocol=None, fix_imports=True)')
 
@@ -2881,10 +2884,10 @@
         foo_sig = MySignature.from_callable(foo)
         self.assertTrue(isinstance(foo_sig, MySignature))
 
+    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_signature_from_callable_builtin_obj(self):
-        import _pickle
         class MySignature(inspect.Signature): pass
         sig = MySignature.from_callable(_pickle.Pickler)
         self.assertTrue(isinstance(sig, MySignature))
@@ -3417,7 +3420,6 @@
     # This test case provides a home for checking that particular APIs
     # have signatures available for introspection
 
-    @cpython_only
     @unittest.skipIf(MISSING_C_DOCSTRINGS,
                      "Signature information for builtins requires docstrings")
     def test_builtins_have_signatures(self):
diff --git a/lib-python/3/test/test_io.py b/lib-python/3/test/test_io.py
--- a/lib-python/3/test/test_io.py
+++ b/lib-python/3/test/test_io.py
@@ -1169,12 +1169,7 @@
         b = bytearray(2*buffer_size)
         self.assertEqual(bufio.peek(3), b'fgh')
         self.assertEqual(rawio._reads, 3)
-        self.assertEqual(bufio.readinto1(b), 6)  # fails because of
-        # an apparent inconsistency in CPython: readinto1(), if the
-        # buffered amount is smaller, would always issue one raw read()
-        # call.  This differs from read1(), which if the buffered amount
-        # if smaller (but more than zero), would just return it without
-        # any raw read() call.  In PyPy both have the behavior of read1().
+        self.assertEqual(bufio.readinto1(b), 6)
         self.assertEqual(b[:6], b"fghjkl")
         self.assertEqual(rawio._reads, 4)
 
diff --git a/lib-python/3/test/test_pydoc.py b/lib-python/3/test/test_pydoc.py
--- a/lib-python/3/test/test_pydoc.py
+++ b/lib-python/3/test/test_pydoc.py
@@ -141,7 +141,7 @@
 <tr bgcolor="#aa55cc">
 <td colspan=3 valign=bottom> <br>
 <font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-
+\x20\x20\x20\x20
 <tr><td bgcolor="#aa55cc"><tt>      </tt></td><td> </td>
 <td width="100%%"><table width="100%%" summary="list"><tr><td width="25%%" valign=top><a href="builtins.html">builtins</a><br>
 </td><td width="25%%" valign=top></td><td width="25%%" valign=top></td><td width="25%%" valign=top></td></tr></table></td></tr></table><p>
@@ -878,7 +878,7 @@
     @requires_docstrings
     def test_unbound_builtin_method(self):
         self.assertEqual(self._get_summary_line(pickle.Pickler.dump),
-            "dump(self, obj, /)")
+            "dump(self, obj)")
 
     # these no longer include "self"
     def test_bound_python_method(self):
@@ -891,13 +891,13 @@
         s = StringIO()
         p = pickle.Pickler(s)
         self.assertEqual(self._get_summary_line(p.dump),
-            "dump(obj, /) method of _pickle.Pickler instance")
+            "dump(obj) method of pickle._Pickler instance")
 
     # this should *never* include self!
     @requires_docstrings
     def test_module_level_callable(self):
         self.assertEqual(self._get_summary_line(os.stat),
-            "stat(path, *, dir_fd=None, follow_symlinks=True)")
+            "stat(path, *, dir_fd=-100, follow_symlinks=True)")
 
 
 @unittest.skipUnless(threading, 'Threading required for this test.')
diff --git a/lib-python/3/test/test_tracemalloc.py b/lib-python/3/test/test_tracemalloc.py
--- a/lib-python/3/test/test_tracemalloc.py
+++ b/lib-python/3/test/test_tracemalloc.py
@@ -1,7 +1,6 @@
 import contextlib
 import os
 import sys
-import tracemalloc
 import unittest
 from unittest.mock import patch
 from test.support.script_helper import (assert_python_ok, assert_python_failure,
@@ -12,6 +11,11 @@
 except ImportError:
     threading = None
 
+try:
+    import tracemalloc
+except ImportError:
+    raise unittest.SkipTest("tracemalloc is required")
+
 EMPTY_STRING_SIZE = sys.getsizeof(b'')
 
 def get_frames(nframe, lineno_delta):
diff --git a/lib-python/3/test/test_unicode.py b/lib-python/3/test/test_unicode.py
--- a/lib-python/3/test/test_unicode.py
+++ b/lib-python/3/test/test_unicode.py
@@ -2396,6 +2396,10 @@
     # Test PyUnicode_FromFormat()
     def test_from_format(self):
         support.import_module('ctypes')
+        try:
+            from ctypes import pythonapi
+        except ImportError:
+            self.skipTest( "no pythonapi in ctypes")
         from ctypes import (
             pythonapi, py_object, sizeof,
             c_int, c_long, c_longlong, c_ssize_t,
diff --git a/lib-python/3/traceback.py b/lib-python/3/traceback.py
--- a/lib-python/3/traceback.py
+++ b/lib-python/3/traceback.py
@@ -544,8 +544,8 @@
             yield '    {}\n'.format(badline.strip())
             if offset is not None:
                 caretspace = badline.rstrip('\n')
-                offset = min(len(caretspace), offset) - 1
-                caretspace = caretspace[:offset].lstrip()
+                # bug in CPython: the case offset==0 is mishandled
+                caretspace = caretspace[:offset].lstrip()[:-1]
                 # non-space whitespace (likes tabs) must be kept for alignment
                 caretspace = ((c.isspace() and c or ' ') for c in caretspace)
                 yield '    {}^\n'.format(''.join(caretspace))
diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/cryptography.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/cryptography.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/cryptography.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/cryptography.py
@@ -48,6 +48,9 @@
 #else
 #define CRYPTOGRAPHY_IS_LIBRESSL 0
 #endif
+
+#define CRYPTOGRAPHY_LIBRESSL_251_OR_GREATER \
+    (CRYPTOGRAPHY_IS_LIBRESSL && LIBRESSL_VERSION_NUMBER >= 0x20501000)
 """
 
 TYPES = """
diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/x509_vfy.py
@@ -244,6 +244,14 @@
 static const long X509_V_FLAG_SUITEB_192_LOS = 0;
 static const long X509_V_FLAG_SUITEB_128_LOS = 0;
 
+#if CRYPTOGRAPHY_LIBRESSL_251_OR_GREATER
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *, const char *, size_t);
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *, const char *, size_t);
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *, const unsigned char *,
+                              size_t);
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *, const char *);
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *, unsigned int);
+#else
 int (*X509_VERIFY_PARAM_set1_host)(X509_VERIFY_PARAM *, const char *,
                                    size_t) = NULL;
 int (*X509_VERIFY_PARAM_set1_email)(X509_VERIFY_PARAM *, const char *,
@@ -254,6 +262,7 @@
 void (*X509_VERIFY_PARAM_set_hostflags)(X509_VERIFY_PARAM *,
                                         unsigned int) = NULL;
 #endif
+#endif
 
 /* OpenSSL 1.0.2+ or Solaris's backport */
 #ifdef X509_V_FLAG_PARTIAL_CHAIN
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -20,9 +20,15 @@
         SSL_ERROR_EOF, SSL_ERROR_NO_SOCKET, SSL_ERROR_INVALID_ERROR_CODE,
         pyerr_write_unraisable)
 from _cffi_ssl._stdssl import error
-from select import poll, POLLIN, POLLOUT, select
+from select import select
 from enum import IntEnum as _IntEnum
 
+if sys.platform == 'win32':
+    HAVE_POLL = False
+else:
+    from select import poll, POLLIN, POLLOUT
+    HAVE_POLL = True
+
 OPENSSL_VERSION = ffi.string(lib.OPENSSL_VERSION_TEXT).decode('utf-8')
 OPENSSL_VERSION_NUMBER = lib.OPENSSL_VERSION_NUMBER
 ver = OPENSSL_VERSION_NUMBER
@@ -158,8 +164,6 @@
     def _monotonic_clock():
         return time.clock_gettime(time.CLOCK_MONOTONIC)
 
-HAVE_POLL = True
-
 def _ssl_select(sock, writing, timeout):
     if HAVE_POLL:
         p = poll()
diff --git a/lib_pypy/_cffi_ssl/osx-roots.diff b/lib_pypy/_cffi_ssl/osx-roots.diff
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_cffi_ssl/osx-roots.diff
@@ -0,0 +1,475 @@
+diff -Naur libressl-2.6.2.orig/crypto/Makefile.am libressl-2.6.2/crypto/Makefile.am
+--- libressl-2.6.2.orig/crypto/Makefile.am	2017-09-02 01:49:55.000000000 +0200
++++ libressl-2.6.2/crypto/Makefile.am	2017-10-07 14:05:16.000000000 +0200
+@@ -92,7 +92,7 @@
+ 	-mv crypto_portable.sym.tmp crypto_portable.sym
+ endif
+ 
+-libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -export-symbols crypto_portable.sym
++libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -export-symbols crypto_portable.sym -framework Security -framework CoreFoundation
+ libcrypto_la_LIBADD = libcompat.la
+ if !HAVE_EXPLICIT_BZERO
+ libcrypto_la_LIBADD += libcompatnoopt.la
+@@ -863,6 +863,7 @@
+ libcrypto_la_SOURCES += x509/x509_txt.c
+ libcrypto_la_SOURCES += x509/x509_v3.c
+ libcrypto_la_SOURCES += x509/x509_vfy.c
++libcrypto_la_SOURCES += x509/x509_vfy_apple.c
+ libcrypto_la_SOURCES += x509/x509_vpm.c
+ libcrypto_la_SOURCES += x509/x509cset.c
+ libcrypto_la_SOURCES += x509/x509name.c
+diff -Naur libressl-2.6.2.orig/crypto/Makefile.in libressl-2.6.2/crypto/Makefile.in
+--- libressl-2.6.2.orig/crypto/Makefile.in	2017-09-26 06:07:03.000000000 +0200
++++ libressl-2.6.2/crypto/Makefile.in	2017-10-07 14:05:24.000000000 +0200
+@@ -426,20 +426,20 @@
+ 	x509/x509_err.c x509/x509_ext.c x509/x509_lu.c x509/x509_obj.c \
+ 	x509/x509_r2x.c x509/x509_req.c x509/x509_set.c \
+ 	x509/x509_trs.c x509/x509_txt.c x509/x509_v3.c x509/x509_vfy.c \
+-	x509/x509_vpm.c x509/x509cset.c x509/x509name.c \
+-	x509/x509rset.c x509/x509spki.c x509/x509type.c x509/x_all.c \
+-	x509v3/pcy_cache.c x509v3/pcy_data.c x509v3/pcy_lib.c \
+-	x509v3/pcy_map.c x509v3/pcy_node.c x509v3/pcy_tree.c \
+-	x509v3/v3_akey.c x509v3/v3_akeya.c x509v3/v3_alt.c \
+-	x509v3/v3_bcons.c x509v3/v3_bitst.c x509v3/v3_conf.c \
+-	x509v3/v3_cpols.c x509v3/v3_crld.c x509v3/v3_enum.c \
+-	x509v3/v3_extku.c x509v3/v3_genn.c x509v3/v3_ia5.c \
+-	x509v3/v3_info.c x509v3/v3_int.c x509v3/v3_lib.c \
+-	x509v3/v3_ncons.c x509v3/v3_ocsp.c x509v3/v3_pci.c \
+-	x509v3/v3_pcia.c x509v3/v3_pcons.c x509v3/v3_pku.c \
+-	x509v3/v3_pmaps.c x509v3/v3_prn.c x509v3/v3_purp.c \
+-	x509v3/v3_skey.c x509v3/v3_sxnet.c x509v3/v3_utl.c \
+-	x509v3/v3err.c
++	x509/x509_vfy_apple.c x509/x509_vpm.c x509/x509cset.c \
++	x509/x509name.c x509/x509rset.c x509/x509spki.c \
++	x509/x509type.c x509/x_all.c x509v3/pcy_cache.c \
++	x509v3/pcy_data.c x509v3/pcy_lib.c x509v3/pcy_map.c \
++	x509v3/pcy_node.c x509v3/pcy_tree.c x509v3/v3_akey.c \
++	x509v3/v3_akeya.c x509v3/v3_alt.c x509v3/v3_bcons.c \
++	x509v3/v3_bitst.c x509v3/v3_conf.c x509v3/v3_cpols.c \
++	x509v3/v3_crld.c x509v3/v3_enum.c x509v3/v3_extku.c \
++	x509v3/v3_genn.c x509v3/v3_ia5.c x509v3/v3_info.c \
++	x509v3/v3_int.c x509v3/v3_lib.c x509v3/v3_ncons.c \
++	x509v3/v3_ocsp.c x509v3/v3_pci.c x509v3/v3_pcia.c \
++	x509v3/v3_pcons.c x509v3/v3_pku.c x509v3/v3_pmaps.c \
++	x509v3/v3_prn.c x509v3/v3_purp.c x509v3/v3_skey.c \
++	x509v3/v3_sxnet.c x509v3/v3_utl.c x509v3/v3err.c
+ am__objects_27 = aes/libcrypto_la-aes-elf-x86_64.lo \
+ 	aes/libcrypto_la-bsaes-elf-x86_64.lo \
+ 	aes/libcrypto_la-vpaes-elf-x86_64.lo \
+@@ -759,11 +759,12 @@
+ 	x509/libcrypto_la-x509_r2x.lo x509/libcrypto_la-x509_req.lo \
+ 	x509/libcrypto_la-x509_set.lo x509/libcrypto_la-x509_trs.lo \
+ 	x509/libcrypto_la-x509_txt.lo x509/libcrypto_la-x509_v3.lo \
+-	x509/libcrypto_la-x509_vfy.lo x509/libcrypto_la-x509_vpm.lo \
+-	x509/libcrypto_la-x509cset.lo x509/libcrypto_la-x509name.lo \
+-	x509/libcrypto_la-x509rset.lo x509/libcrypto_la-x509spki.lo \
+-	x509/libcrypto_la-x509type.lo x509/libcrypto_la-x_all.lo \
+-	x509v3/libcrypto_la-pcy_cache.lo \
++	x509/libcrypto_la-x509_vfy.lo \
++	x509/libcrypto_la-x509_vfy_apple.lo \
++	x509/libcrypto_la-x509_vpm.lo x509/libcrypto_la-x509cset.lo \
++	x509/libcrypto_la-x509name.lo x509/libcrypto_la-x509rset.lo \
++	x509/libcrypto_la-x509spki.lo x509/libcrypto_la-x509type.lo \
++	x509/libcrypto_la-x_all.lo x509v3/libcrypto_la-pcy_cache.lo \
+ 	x509v3/libcrypto_la-pcy_data.lo x509v3/libcrypto_la-pcy_lib.lo \
+ 	x509v3/libcrypto_la-pcy_map.lo x509v3/libcrypto_la-pcy_node.lo \
+ 	x509v3/libcrypto_la-pcy_tree.lo x509v3/libcrypto_la-v3_akey.lo \
+@@ -1000,7 +1001,7 @@
+ 	$(ASM_X86_64_ELF) $(ASM_X86_64_MACOSX)
+ BUILT_SOURCES = crypto_portable.sym
+ CLEANFILES = crypto_portable.sym
+-libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -export-symbols crypto_portable.sym
++libcrypto_la_LDFLAGS = -version-info @LIBCRYPTO_VERSION@ -no-undefined -export-symbols crypto_portable.sym -framework Security -framework CoreFoundation
+ libcrypto_la_LIBADD = libcompat.la $(am__append_1)
+ libcrypto_la_CPPFLAGS = $(AM_CPPFLAGS) -DLIBRESSL_INTERNAL \
+ 	-DOPENSSL_NO_HW_PADLOCK $(am__append_2) $(am__append_3) \
+@@ -1272,20 +1273,20 @@
+ 	x509/x509_err.c x509/x509_ext.c x509/x509_lu.c x509/x509_obj.c \
+ 	x509/x509_r2x.c x509/x509_req.c x509/x509_set.c \
+ 	x509/x509_trs.c x509/x509_txt.c x509/x509_v3.c x509/x509_vfy.c \
+-	x509/x509_vpm.c x509/x509cset.c x509/x509name.c \
+-	x509/x509rset.c x509/x509spki.c x509/x509type.c x509/x_all.c \
+-	x509v3/pcy_cache.c x509v3/pcy_data.c x509v3/pcy_lib.c \
+-	x509v3/pcy_map.c x509v3/pcy_node.c x509v3/pcy_tree.c \
+-	x509v3/v3_akey.c x509v3/v3_akeya.c x509v3/v3_alt.c \
+-	x509v3/v3_bcons.c x509v3/v3_bitst.c x509v3/v3_conf.c \
+-	x509v3/v3_cpols.c x509v3/v3_crld.c x509v3/v3_enum.c \
+-	x509v3/v3_extku.c x509v3/v3_genn.c x509v3/v3_ia5.c \
+-	x509v3/v3_info.c x509v3/v3_int.c x509v3/v3_lib.c \
+-	x509v3/v3_ncons.c x509v3/v3_ocsp.c x509v3/v3_pci.c \
+-	x509v3/v3_pcia.c x509v3/v3_pcons.c x509v3/v3_pku.c \
+-	x509v3/v3_pmaps.c x509v3/v3_prn.c x509v3/v3_purp.c \
+-	x509v3/v3_skey.c x509v3/v3_sxnet.c x509v3/v3_utl.c \
+-	x509v3/v3err.c
++	x509/x509_vfy_apple.c x509/x509_vpm.c x509/x509cset.c \
++	x509/x509name.c x509/x509rset.c x509/x509spki.c \
++	x509/x509type.c x509/x_all.c x509v3/pcy_cache.c \
++	x509v3/pcy_data.c x509v3/pcy_lib.c x509v3/pcy_map.c \
++	x509v3/pcy_node.c x509v3/pcy_tree.c x509v3/v3_akey.c \
++	x509v3/v3_akeya.c x509v3/v3_alt.c x509v3/v3_bcons.c \
++	x509v3/v3_bitst.c x509v3/v3_conf.c x509v3/v3_cpols.c \
++	x509v3/v3_crld.c x509v3/v3_enum.c x509v3/v3_extku.c \
++	x509v3/v3_genn.c x509v3/v3_ia5.c x509v3/v3_info.c \
++	x509v3/v3_int.c x509v3/v3_lib.c x509v3/v3_ncons.c \
++	x509v3/v3_ocsp.c x509v3/v3_pci.c x509v3/v3_pcia.c \
++	x509v3/v3_pcons.c x509v3/v3_pku.c x509v3/v3_pmaps.c \
++	x509v3/v3_prn.c x509v3/v3_purp.c x509v3/v3_skey.c \
++	x509v3/v3_sxnet.c x509v3/v3_utl.c x509v3/v3err.c
+ 
+ # chacha
+ 
+@@ -2808,6 +2809,8 @@
+ 	x509/$(DEPDIR)/$(am__dirstamp)
+ x509/libcrypto_la-x509_vfy.lo: x509/$(am__dirstamp) \
+ 	x509/$(DEPDIR)/$(am__dirstamp)
++x509/libcrypto_la-x509_vfy_apple.lo: x509/$(am__dirstamp) \
++	x509/$(DEPDIR)/$(am__dirstamp)
+ x509/libcrypto_la-x509_vpm.lo: x509/$(am__dirstamp) \
+ 	x509/$(DEPDIR)/$(am__dirstamp)
+ x509/libcrypto_la-x509cset.lo: x509/$(am__dirstamp) \
+@@ -3583,6 +3586,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509_txt.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509_v3.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509_vfy.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509_vfy_apple.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509_vpm.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509cset.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at x509/$(DEPDIR)/libcrypto_la-x509name.Plo at am__quote@
+@@ -7460,6 +7464,13 @@
+ @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509/libcrypto_la-x509_vfy.lo `test -f 'x509/x509_vfy.c' || echo '$(srcdir)/'`x509/x509_vfy.c
+ 
++x509/libcrypto_la-x509_vfy_apple.lo: x509/x509_vfy_apple.c
++ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509/libcrypto_la-x509_vfy_apple.lo -MD -MP -MF x509/$(DEPDIR)/libcrypto_la-x509_vfy_apple.Tpo -c -o x509/libcrypto_la-x509_vfy_apple.lo `test -f 'x509/x509_vfy_apple.c' || echo '$(srcdir)/'`x509/x509_vfy_apple.c
++ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) x509/$(DEPDIR)/libcrypto_la-x509_vfy_apple.Tpo x509/$(DEPDIR)/libcrypto_la-x509_vfy_apple.Plo
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='x509/x509_vfy_apple.c' object='x509/libcrypto_la-x509_vfy_apple.lo' libtool=yes @AMDEPBACKSLASH@
++ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509/libcrypto_la-x509_vfy_apple.lo `test -f 'x509/x509_vfy_apple.c' || echo '$(srcdir)/'`x509/x509_vfy_apple.c
++
+ x509/libcrypto_la-x509_vpm.lo: x509/x509_vpm.c
+ @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509/libcrypto_la-x509_vpm.lo -MD -MP -MF x509/$(DEPDIR)/libcrypto_la-x509_vpm.Tpo -c -o x509/libcrypto_la-x509_vpm.lo `test -f 'x509/x509_vpm.c' || echo '$(srcdir)/'`x509/x509_vpm.c
+ @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) x509/$(DEPDIR)/libcrypto_la-x509_vpm.Tpo x509/$(DEPDIR)/libcrypto_la-x509_vpm.Plo
+diff -Naur libressl-2.6.2.orig/crypto/x509/x509_vfy.c libressl-2.6.2/crypto/x509/x509_vfy.c
+--- libressl-2.6.2.orig/crypto/x509/x509_vfy.c	2017-09-02 14:01:08.000000000 +0200
++++ libressl-2.6.2/crypto/x509/x509_vfy.c	2017-10-07 14:05:16.000000000 +0200
+@@ -115,6 +115,13 @@
+ 
+ #define CRL_SCORE_TIME_DELTA	0x002
+ 
++/*
++ * If we are using Trust Evaluation Agent, rename the original function
++ */
++#ifdef __APPLE__
++#define X509_verify_cert X509_verify_cert_orig
++#endif
++
+ static int null_callback(int ok, X509_STORE_CTX *e);
+ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
+diff -Naur libressl-2.6.2.orig/crypto/x509/x509_vfy_apple.c libressl-2.6.2/crypto/x509/x509_vfy_apple.c
+--- libressl-2.6.2.orig/crypto/x509/x509_vfy_apple.c	1970-01-01 01:00:00.000000000 +0100
++++ libressl-2.6.2/crypto/x509/x509_vfy_apple.c	2017-10-07 14:05:16.000000000 +0200
+@@ -0,0 +1,225 @@
++/*
++ * Copyright (c) 2009 Apple Inc. All Rights Reserved.
++ *
++ * @APPLE_LICENSE_HEADER_START@
++ * 
++ * This file contains Original Code and/or Modifications of Original Code
++ * as defined in and that are subject to the Apple Public Source License
++ * Version 2.0 (the 'License'). You may not use this file except in
++ * compliance with the License. Please obtain a copy of the License at
++ * http://www.opensource.apple.com/apsl/ and read it before using this
++ * file.
++ * 
++ * The Original Code and all software distributed under the License are
++ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
++ * Please see the License for the specific language governing rights and
++ * limitations under the License.
++ * 
++ * @APPLE_LICENSE_HEADER_END@
++ *
++ */
++
++#include <stdint.h>
++#include <inttypes.h>
++#include <syslog.h>
++
++#include <Security/Security.h>
++
++#include <openssl/opensslconf.h>
++
++#include <openssl/crypto.h>
++#include <openssl/x509.h>
++#include <openssl/x509v3.h>
++
++#include "cryptlib.h"
++#include "vpm_int.h"
++#include "x509_vfy_apple.h"
++
++#define TEA_might_correct_error(err) (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT || err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
++
++
++static bool add_cert_to_array(CFMutableArrayRef array, X509 *x509)
++{
++    unsigned char *asn1_cert_data = NULL;
++    int asn1_cert_len = i2d_X509(x509, &asn1_cert_data);
++
++    CFDataRef data = CFDataCreate(kCFAllocatorDefault, asn1_cert_data, asn1_cert_len);
++
++    if (data == NULL) {
++        return false;
++    }
++
++    SecCertificateRef cert = SecCertificateCreateWithData(NULL, data);
++
++    free(asn1_cert_data);
++
++    if (cert == NULL) {
++        CFRelease(data);
++        return false;
++    }
++
++    CFArrayAppendValue(array, cert);
++    CFRelease(data);
++
++    return true;
++}
++
++static CFStringRef to_string(const char *s) {
++    if (s == NULL)
++        return NULL;
++    return CFStringCreateWithCString(kCFAllocatorDefault, s,
++                                     kCFStringEncodingASCII);
++}
++
++static SecPolicyRef get_policy(X509_VERIFY_PARAM *param) {
++    switch (param->purpose) {
++        case X509_PURPOSE_SSL_CLIENT:
++        case X509_PURPOSE_SSL_SERVER: {
++
++            if (!param->id) {
++                fprintf(stderr, "got no ID!\n");
++                return NULL;
++            }
++
++            CFStringRef hostname;
++            int nhosts = sk_OPENSSL_STRING_num(param->id->hosts);
++
++            if (nhosts != 1) {
++                hostname = NULL;
++
++            } else {
++                hostname = to_string(sk_OPENSSL_STRING_value(param->id->hosts, 0));
++                CFShow(hostname);
++            }
++            
++            return SecPolicyCreateSSL(param->purpose == X509_PURPOSE_SSL_SERVER,
++                                      hostname);
++        }
++
++        case X509_PURPOSE_NS_SSL_SERVER:
++        case X509_PURPOSE_SMIME_SIGN:
++        case X509_PURPOSE_SMIME_ENCRYPT:
++        case X509_PURPOSE_CRL_SIGN:
++        case X509_PURPOSE_ANY:
++        case X509_PURPOSE_OCSP_HELPER:
++        case X509_PURPOSE_TIMESTAMP_SIGN:
++        default:
++            fprintf(stderr, "unsupported purpose %d", param->purpose);
++            return NULL;
++    }
++}
++
++/*
++ * Please see comment in x509_vfy_apple.h
++ */
++int
++X509_verify_cert(X509_STORE_CTX *ctx)
++{
++	uint64_t		certLastIndex = 0;
++	uint64_t		i = 0;
++
++    /* Try OpenSSL, if we get a local certificate issue verify against trusted roots */
++    int ret = X509_verify_cert_orig(ctx);
++    
++    /* Verify TEA is enabled and should be used. */
++    if (0 == X509_TEA_is_enabled() ||
++        ret == 1 || !TEA_might_correct_error(ctx->error)) {
++        return ret;
++    }
++    
++    /* Verify that the certificate chain exists, otherwise make it. */
++    if (ctx->chain == NULL && (ctx->chain = sk_X509_new_null()) == NULL) {
++        fprintf(stderr, "Could not create the certificate chain");
++        ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
++        return -1;
++    }
++    
++    /* Verify chain depth */
++    certLastIndex = sk_X509_num(ctx->untrusted);
++    if (certLastIndex > ctx->param->depth) {
++        fprintf(stderr, "Pruning certificate chain to %" PRIu64, certLastIndex);
++        certLastIndex = ctx->param->depth;
++    }
++
++    CFMutableArrayRef certArray = CFArrayCreateMutable(NULL, certLastIndex + 1, NULL);
++    CFRetain(certArray);
++    
++    if (!add_cert_to_array(certArray, ctx->cert)) {
++        fprintf(stderr, "Failed to add certificate to array");
++        CFRelease(certArray);
++        ctx->error = X509_V_ERR_UNSPECIFIED;
++        return -1;
++    }
++    
++    for (i = 0; i < certLastIndex; ++i) {
++        X509	*t = sk_X509_value(ctx->untrusted, i);
++        if (!add_cert_to_array(certArray, t)) {
++            fprintf(stderr, "Failed to add chain certificate %lld to array", i);
++            CFRelease(certArray);
++            ctx->error = X509_V_ERR_UNSPECIFIED;
++            return 0;
++        }
++    }
++    
++    // We put ASN.1 encoded X509 on the CertificateChain, so we don't call TEACertificateChainSetEncodingHandler
++    SecPolicyRef policy = get_policy(ctx->param);
++    
++    if (policy == NULL) {
++        fprintf(stderr, "Failed to create policy!\n");
++        CFRelease(certArray);
++        ctx->error = X509_V_ERR_UNSPECIFIED;
++        return -1;
++    }
++
++    SecTrustRef trust = NULL;
++
++    if (SecTrustCreateWithCertificates(certArray, policy, &trust)  != errSecSuccess) {
++        fprintf(stderr, "Failed to create trust!\n");
++        CFRelease(certArray);
++        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
++        return -1;
++    }
++
++    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
++        fprintf(stderr, "Setting time not supported yet?\n");
++        SecTrustSetVerifyDate(trust, CFDateCreate(NULL, ctx->param->check_time));
++    }
++
++    SecTrustResultType result = 0;
++
++    if (SecTrustEvaluate(trust, &result) != errSecSuccess || result != kSecTrustResultUnspecified) {
++        CFRelease(certArray);
++        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
++        return 0;
++    }
++
++    CFRelease(certArray);
++    ctx->error = 0;
++    return 1;
++}
++
++#pragma mark Trust Evaluation Agent
++
++/* -1: not set
++ *  0: set to false
++ *  1: set to true
++ */
++static int tea_enabled = -1;
++
++void
++X509_TEA_set_state(int change)
++{
++	tea_enabled = (change) ? 1 : 0;
++}
++
++int
++X509_TEA_is_enabled()
++{
++	if (tea_enabled < 0)
++		tea_enabled = (NULL == getenv(X509_TEA_ENV_DISABLE));
++
++	return tea_enabled != 0;
++}
+diff -Naur libressl-2.6.2.orig/crypto/x509/x509_vfy_apple.h libressl-2.6.2/crypto/x509/x509_vfy_apple.h
+--- libressl-2.6.2.orig/crypto/x509/x509_vfy_apple.h	1970-01-01 01:00:00.000000000 +0100
++++ libressl-2.6.2/crypto/x509/x509_vfy_apple.h	2017-10-07 14:05:16.000000000 +0200
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2009 Apple Inc. All Rights Reserved.
++ *
++ * @APPLE_LICENSE_HEADER_START@
++ * 
++ * This file contains Original Code and/or Modifications of Original Code
++ * as defined in and that are subject to the Apple Public Source License
++ * Version 2.0 (the 'License'). You may not use this file except in
++ * compliance with the License. Please obtain a copy of the License at
++ * http://www.opensource.apple.com/apsl/ and read it before using this
++ * file.
++ * 
++ * The Original Code and all software distributed under the License are
++ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
++ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
++ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
++ * Please see the License for the specific language governing rights and
++ * limitations under the License.
++ * 
++ * @APPLE_LICENSE_HEADER_END@
++ *
++ */
++
++#ifndef HEADER_X509_H
++#include <openssl/x509.h>
++#endif
++
++#ifndef HEADER_X509_VFY_APPLE_H
++#define HEADER_X509_VFY_APPLE_H
++
++/* Environment variable name to disable TEA. */
++#define X509_TEA_ENV_DISABLE "OPENSSL_X509_TEA_DISABLE"
++
++/*
++ * X509_verify_cert
++ *
++ * Originally located in x509_vfy.c.
++ *
++ * Verify certificate with OpenSSL created X509_verify_cert. If and only if
++ * OpenSSL cannot get certificate issuer locally then OS X security API will
++ * verify the certificate, using Trust Evaluation Agent.
++ *
++ * Return values:
++ * --------------
++ * -1: Null was passed for either ctx or ctx->cert.
++ *  0: Certificate is trusted.
++ *  1: Certificate is not trusted.
++ */
++int X509_verify_cert(X509_STORE_CTX *ctx);
++
++/*
++ * X509_TEA_is_enabled
++ *
++ * Is the Trust Evaluation Agent (TEA) used for certificate verification when
++ * the issuer cannot be verified.
++ *
++ * Returns 0 if TEA is disabled and 1 if TEA is enabled.
++ */
++int X509_TEA_is_enabled();
++
++/*
++ * X509_TEA_set_state
++ *
++ * Enables/disables certificate verification with Trust Evaluation Agent (TEA)
++ * when the issuer cannot be verified.
++ *
++ * Pass 0 to disable TEA and non-zero to enable TEA.
++ */
++void X509_TEA_set_state(int change);
++
++int X509_verify_cert_orig(X509_STORE_CTX *ctx);
++
++#endif /* HEADER_X509_VFY_APPLE_H */
diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -8,9 +8,14 @@
 class ArrayMeta(_CDataMeta):
     def __new__(self, name, cls, typedict):
         res = type.__new__(self, name, cls, typedict)
+
         if cls == (_CData,): # this is the Array class defined below
+            res._ffiarray = None
             return res
-
+        if not hasattr(res, '_length_') or not isinstance(res._length_, int):
+            raise AttributeError(
+                "class must define a '_length_' attribute, "
+                "which must be a positive integer")
         ffiarray = res._ffiarray = _rawffi.Array(res._type_._ffishape_)
         subletter = getattr(res._type_, '_type_', None)
         if subletter == 'c':
@@ -55,7 +60,7 @@
                 for i in range(len(val)):
                     target[i] = val[i]
                 if len(val) < self._length_:
-                    target[len(val)] = '\x00'
+                    target[len(val)] = u'\x00'
             res.value = property(getvalue, setvalue)
 
         res._ffishape_ = (ffiarray, res._length_)
@@ -164,7 +169,7 @@
     if letter == 'c':
         return b"".join(l)
     if letter == 'u':
-        return "".join(l)
+        return u"".join(l)
     return l
 
 class Array(_CData, metaclass=ArrayMeta):
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -165,6 +165,10 @@
     def _get_buffer_value(self):
         return self._buffer[0]
 
+    def _copy_to(self, addr):
+        target = type(self).from_address(addr)._buffer
+        target[0] = self._get_buffer_value()
+
     def _to_ffi_param(self):
         if self.__class__._is_pointer_like():
             return self._get_buffer_value()
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -113,7 +113,9 @@
         cobj = self._type_.from_param(value)
         if ensure_objects(cobj) is not None:
             store_reference(self, index, cobj._objects)
-        self._subarray(index)[0] = cobj._get_buffer_value()
+        address = self._buffer[0]
+        address += index * sizeof(self._type_)
+        cobj._copy_to(address)
 
     def __bool__(self):
         return self._buffer[0] != 0
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -232,9 +232,6 @@
 
         elif tp == 'u':
             def _setvalue(self, val):
-                if isinstance(val, bytes):
-                    val = val.decode(ConvMode.encoding, ConvMode.errors)
-                # possible if we use 'ignore'
                 if val:
                     self._buffer[0] = val
             def _getvalue(self):
@@ -243,8 +240,6 @@
 
         elif tp == 'c':
             def _setvalue(self, val):
-                if isinstance(val, str):
-                    val = val.encode(ConvMode.encoding, ConvMode.errors)
                 if val:
                     self._buffer[0] = val
             def _getvalue(self):
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -290,6 +290,11 @@
     def _get_buffer_value(self):
         return self._buffer.buffer
 
+    def _copy_to(self, addr):
+        from ctypes import memmove
+        origin = self._get_buffer_value()
+        memmove(addr, origin, self._fficompositesize_)
+
     def _to_ffi_param(self):
         return self._buffer
 
diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py
--- a/lib_pypy/_ctypes_test.py
+++ b/lib_pypy/_ctypes_test.py
@@ -21,5 +21,11 @@
         with fp:
             imp.load_module('_ctypes_test', fp, filename, description)
     except ImportError:
+        if os.name == 'nt':
+            # hack around finding compilers on win32
+            try:
+                import setuptools
+            except ImportError:
+                pass
         print('could not find _ctypes_test in %s' % output_dir)
         _pypy_testcapi.compile_shared('_ctypes_test.c', '_ctypes_test', output_dir)
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -404,7 +404,7 @@
         return val
 
     def get_wch(self, *args):
-        wch = ffi.new("int[1]")
+        wch = ffi.new("wint_t[1]")
         if len(args) == 0:
             val = lib.wget_wch(self._win, wch)
         elif len(args) == 2:
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -8,7 +8,8 @@
         content = fid.read()
     # from cffi's Verifier()
     key = '\x00'.join([sys.version[:3], content])
-    key += 'cpyext-gc-support-2'   # this branch requires recompilation!
+    # change the key to force recompilation
+    key += '2017-11-21'
     if sys.version_info >= (3,):
         key = key.encode('utf-8')
     k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1080,21 +1080,25 @@
         if '\0' in sql:
             raise ValueError("the query contains a null character")
 
-        first_word = sql.lstrip().split(" ")[0].upper()
-        if first_word == "":
+        
+        if sql:
+            first_word = sql.lstrip().split()[0].upper()
+            if first_word == '':
+                self._type = _STMT_TYPE_INVALID
+            if first_word == "SELECT":
+                self._type = _STMT_TYPE_SELECT
+            elif first_word == "INSERT":
+                self._type = _STMT_TYPE_INSERT
+            elif first_word == "UPDATE":
+                self._type = _STMT_TYPE_UPDATE
+            elif first_word == "DELETE":
+                self._type = _STMT_TYPE_DELETE
+            elif first_word == "REPLACE":
+                self._type = _STMT_TYPE_REPLACE
+            else:
+                self._type = _STMT_TYPE_OTHER
+        else:
             self._type = _STMT_TYPE_INVALID
-        elif first_word == "SELECT":
-            self._type = _STMT_TYPE_SELECT
-        elif first_word == "INSERT":
-            self._type = _STMT_TYPE_INSERT
-        elif first_word == "UPDATE":
-            self._type = _STMT_TYPE_UPDATE
-        elif first_word == "DELETE":
-            self._type = _STMT_TYPE_DELETE
-        elif first_word == "REPLACE":
-            self._type = _STMT_TYPE_REPLACE
-        else:
-            self._type = _STMT_TYPE_OTHER
 
         if isinstance(sql, unicode):
             sql = sql.encode('utf-8')
diff --git a/lib_pypy/_ssl/__init__.py b/lib_pypy/_ssl/__init__.py
--- a/lib_pypy/_ssl/__init__.py
+++ b/lib_pypy/_ssl/__init__.py
@@ -14,3 +14,14 @@
 # RAND_egd is optional and might not be available on e.g. libressl
 if hasattr(_stdssl, 'RAND_egd'):
     RAND_egd          = builtinify(RAND_egd)
+
+import sys
+if sys.platform == "win32" and 'enum_certificates' not in globals():
+    def enum_certificates(*args, **kwds):
+        import warnings
+        warnings.warn("ssl.enum_certificates() is not implemented")
+        return []
+    def enum_crls(*args, **kwds):
+        import warnings
+        warnings.warn("ssl.enum_crls() is not implemented")
+        return []
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_testcapi.py
@@ -17,6 +17,12 @@
         with fp:
             imp.load_module('_testcapi', fp, filename, description)
     except ImportError:
+        if os.name == 'nt':
+            # hack around finding compilers on win32
+            try:
+                import setuptools
+            except ImportError:
+                pass
         _pypy_testcapi.compile_shared(cfile, '_testcapi', output_dir)
 
 
diff --git a/lib_pypy/_testcapimodule.c b/lib_pypy/_testcapimodule.c
--- a/lib_pypy/_testcapimodule.c
+++ b/lib_pypy/_testcapimodule.c
@@ -915,12 +915,6 @@
         return -1;
     }
     Py_DECREF(res);
-    if (Py_REFCNT(arg) != 1) {
-        PyErr_Format(TestError, "test_buildvalue_N: "
-                     "arg was not decrefed in successful "
-                     "Py_BuildValue(\"%s\")", fmt);
-        return -1;
-    }
 


More information about the pypy-commit mailing list