python-trio / hip

A new Python HTTP client for everybody

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mysterious PyPy2 test case failure

pquentin opened this issue · comments

We just merged this new test from urllib3's master branch, and it fails on Travis with PyPy 2 with the following traceback:

____________ test_wrap_socket_given_ca_certs_no_load_default_certs _____________
Traceback (most recent call last):
  File ".../urllib3/test/test_ssl.py", line 111, in test_wrap_socket_given_ca_certs_no_load_default_certs
    ssl_.ssl_wrap_socket(sock, ca_certs="/tmp/fake-file")
  File ".../urllib3/.tox/pypy/site-packages/urllib3/util/ssl_.py", line 382, in ssl_wrap_socket
    context.load_verify_locations(ca_certs, ca_cert_dir)
  File ".../urllib3/.tox/pypy/site-packages/mock/mock.py", line 1061, in __call__
    _mock_self._mock_check_sig(*args, **kwargs)
  File ".../urllib3/.tox/pypy/site-packages/mock/mock.py", line 209, in checksig
    sig.bind(*args, **kwargs)
  File ".../urllib3/.tox/pypy/site-packages/funcsigs/__init__.py", line 792, in bind
    return args[0]._bind(args[1:], kwargs)
  File ".../urllib3/.tox/pypy/site-packages/funcsigs/__init__.py", line 717, in _bind
    raise TypeError(msg)
TypeError: 'cadata' parameter lacking default value

The traceback is also recorded in the commit message, and you can currently see it in the urllib3/urllib master builds. For example in https://travis-ci.org/urllib3/urllib3/jobs/572772982 (search for test_wrap_socket_given_ca_certs_no_load_default_certs).

Possibly relevant metadata:

$ python --version
Python 2.7.13 (ab0b9caf307db6592905a80b8faffd69b39005b8, Apr 30 2018, 08:21:35)
[PyPy 6.0.0 with GCC 7.2.0]
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.1.0h  27 Mar 2018

Anyway, the test fails with TypeError: 'cadata' parameter lacking default value in an autospec mock. cadata is a parameter that was added to SSLContext.load_verify_locations in the standard library ssl module in CPython 2.7.9. (CPython 2.7.9 was released in December 2014 and backported the whole ssl module from Python 3.4.)

For CPython < 2.7.9, urllib3 provides a custom SSLContext that only exposes the available options, so for example load_verify_locations is called without cadata. At some point, PyPy was probably just calling OpenSSL's SSL_CTX_load_verify_locations directly, but if I understand correctly then had to switch to the CPython implementation to support cadata.

Okay, so, it looks like it's a mock/funcsigs bug they decided not to fix: testing-cabal/mock#438. What needs to be done here is to link to this issue and to the mock issue in the code, and I thus mark this as a good first issue!

To be clear, the idea here is to add something like this upstream (ie. urllib3/urllib3):

 def test_wrap_socket_given_ca_certs_no_load_default_certs(monkeypatch):
+   if platform.python_implementation() == 'PyPy' and sys.version_info[0] == 2:
+        # https://github.com/testing-cabal/mock/issues/438
+        pytest.xfail("test is expected to fail with PyPy 2")
    context = mock.create_autospec(ssl_.SSLContext)
    context.load_default_certs = mock.Mock()
    context.options = 0

We now have the fix, both upstream and here.