From 5a67290bf5b06f029ce4f9ee56f3d798a3400573 Mon Sep 17 00:00:00 2001 From: Fantix King Date: Mon, 10 Dec 2012 14:36:13 +0800 Subject: [PATCH] Refs #38, fixed ssl.py and the rest failing tests. --- gevent/core.ppyx | 2 + gevent/socket.py | 12 ++-- gevent/ssl.py | 73 ++++++++++++++++++------ greentest/lock_tests.py | 13 ++++- greentest/test__ssl.py | 6 +- greentest/test__threading_vs_settrace.py | 4 +- greentest/test_threading_2.py | 27 ++++++--- 7 files changed, 100 insertions(+), 37 deletions(-) diff --git a/gevent/core.ppyx b/gevent/core.ppyx index a44a2be84..c723c61d1 100644 --- a/gevent/core.ppyx +++ b/gevent/core.ppyx @@ -341,6 +341,8 @@ cdef public class loop [object PyGeventLoopObject, type PyGeventLoop_Type]: return libev.EV_MINPRI def _handle_syserr(self, message, errno): + if sys.version_info[0] >= 3: + message = message.decode() self.handle_error(None, SystemError, SystemError(message + ': ' + os.strerror(errno)), None) cpdef handle_error(self, context, type, value, tb): diff --git a/gevent/socket.py b/gevent/socket.py index fb64411cb..96d289f83 100644 --- a/gevent/socket.py +++ b/gevent/socket.py @@ -112,13 +112,14 @@ EBADF = 9 import _socket -_realsocket = _socket.socket import socket as __socket__ -try: - _fileobject = __socket__._fileobject -except AttributeError: +if PY3: from socket import socket as __socket__socket__ + # for ssl.py to create weakref + class _realsocket(_socket.socket): + pass + class _fileobject: def __init__(self, sock, mode='rwb', bufsize=-1, close=False): super().__init__() @@ -153,6 +154,9 @@ def close(self): return getattr(self._obj, '%s')(*args, **kwargs) ''' % (_name, _name)) del _name +else: + _fileobject = __socket__._fileobject + _realsocket = _socket.socket for name in __imports__[:]: diff --git a/gevent/ssl.py b/gevent/ssl.py index c6f328ea2..cdbe72578 100644 --- a/gevent/ssl.py +++ b/gevent/ssl.py @@ -23,7 +23,7 @@ import errno from gevent.socket import socket, _fileobject, timeout_default from gevent.socket import error as socket_error -from gevent.hub import integer_types, text_type, binary_type, PY3 +from gevent.hub import integer_types, text_type, binary_type, PY3, b __implements__ = ['SSLSocket', @@ -67,7 +67,7 @@ def __init__(self, sock, keyfile=None, certfile=None, ssl_version=PROTOCOL_SSLv23, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, - ciphers=None): + ciphers=None, server_hostname=None, _context=None): socket.__init__(self, _sock=sock) if certfile and not keyfile: @@ -83,15 +83,46 @@ def __init__(self, sock, keyfile=None, certfile=None, self._sslobj = None else: # yes, create the SSL object - if ciphers is None: - self._sslobj = _ssl.sslwrap(self._sock, server_side, - keyfile, certfile, - cert_reqs, ssl_version, ca_certs) + if PY3: + self._sslobj = None + if _context: + self.context = _context + else: + if server_side and not certfile: + raise ValueError("certfile must be specified for " + "server-side operations") + if keyfile and not certfile: + raise ValueError("certfile must be specified") + if certfile and not keyfile: + keyfile = certfile + self.context = __ssl__._SSLContext(ssl_version) + self.context.verify_mode = cert_reqs + if ca_certs: + self.context.load_verify_locations(ca_certs) + if certfile: + self.context.load_cert_chain(certfile, keyfile) + if ciphers: + self.context.set_ciphers(ciphers) + if server_side and server_hostname: + raise ValueError("server_hostname can only be specified " + "in client mode") + self.server_hostname = server_hostname + try: + self._sslobj = self.context._wrap_socket( + self._sock, server_side, server_hostname) + except socket_error as e: + self.close() + raise e else: - self._sslobj = _ssl.sslwrap(self._sock, server_side, - keyfile, certfile, - cert_reqs, ssl_version, ca_certs, - ciphers) + if ciphers is None: + self._sslobj = _ssl.sslwrap(self._sock, server_side, + keyfile, certfile, + cert_reqs, ssl_version, ca_certs) + else: + self._sslobj = _ssl.sslwrap(self._sock, server_side, + keyfile, certfile, + cert_reqs, ssl_version, ca_certs, + ciphers) if do_handshake_on_connect: self.do_handshake() self.keyfile = keyfile @@ -113,7 +144,7 @@ def read(self, len=1024): except SSLError: ex = sys.exc_info()[1] if ex.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: - return '' + return b('') elif ex.args[0] == SSL_ERROR_WANT_READ: if self.timeout == 0.0: raise @@ -372,14 +403,18 @@ def connect(self, addr): if self._sslobj: raise ValueError("attempt to connect already-connected SSLSocket!") socket.connect(self, addr) - if self.ciphers is None: - self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile, - self.cert_reqs, self.ssl_version, - self.ca_certs) + if PY3: + self._sslobj = self.context._wrap_socket(self._sock, False, + self.server_hostname) else: - self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile, - self.cert_reqs, self.ssl_version, - self.ca_certs, self.ciphers) + if self.ciphers is None: + self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile, + self.cert_reqs, self.ssl_version, + self.ca_certs) + else: + self._sslobj = _ssl.sslwrap(self._sock, False, self.keyfile, self.certfile, + self.cert_reqs, self.ssl_version, + self.ca_certs, self.ciphers) if self.do_handshake_on_connect: self.do_handshake() @@ -400,7 +435,7 @@ def accept(self): ciphers=self.ciphers), addr) - def makefile(self, mode='r', bufsize=-1): + def makefile(self, mode='rwb', bufsize=-1): """Make and return a file-like object that works with the SSL connection. Just use the code from the socket module.""" diff --git a/greentest/lock_tests.py b/greentest/lock_tests.py index 59cdf99e8..08e4e27e4 100644 --- a/greentest/lock_tests.py +++ b/greentest/lock_tests.py @@ -3,13 +3,17 @@ """ from __future__ import with_statement +import six import sys import time -from thread import start_new_thread, get_ident +try: + from thread import start_new_thread, get_ident +except ImportError: + from _thread import start_new_thread, get_ident import threading import unittest -from test import test_support as support +import test_support as support def _wait(): @@ -419,7 +423,10 @@ class BaseSemaphoreTests(BaseTestCase): def test_constructor(self): self.assertRaises(ValueError, self.semtype, value = -1) - self.assertRaises(ValueError, self.semtype, value = -sys.maxint) + if six.PY3: + self.assertRaises(ValueError, self.semtype, value = -sys.maxsize) + else: + self.assertRaises(ValueError, self.semtype, value = -sys.maxint) def test_acquire(self): sem = self.semtype(1) diff --git a/greentest/test__ssl.py b/greentest/test__ssl.py index afe59ac98..4dc06361d 100644 --- a/greentest/test__ssl.py +++ b/greentest/test__ssl.py @@ -2,6 +2,10 @@ import os import socket import greentest +try: + from socket import sslerror +except ImportError: + from ssl import SSLError as sslerror from test__socket import TestTCP import ssl @@ -10,7 +14,7 @@ class TestSSL(TestTCP): certfile = os.path.join(os.path.dirname(__file__), 'test_server.crt') privfile = os.path.join(os.path.dirname(__file__), 'test_server.key') - TIMEOUT_ERROR = socket.sslerror + TIMEOUT_ERROR = sslerror def setUp(self): greentest.TestCase.setUp(self) diff --git a/greentest/test__threading_vs_settrace.py b/greentest/test__threading_vs_settrace.py index 961019ccd..e53a6ff8f 100644 --- a/greentest/test__threading_vs_settrace.py +++ b/greentest/test__threading_vs_settrace.py @@ -81,5 +81,5 @@ def test_bootstrap_inner_with_trace(self): if __name__ == "__main__": - import test.test_support - test.test_support.run_unittest(ThreadTrace) + import test_support + test_support.run_unittest(ThreadTrace) diff --git a/greentest/test_threading_2.py b/greentest/test_threading_2.py index bc151cf89..543877ff4 100644 --- a/greentest/test_threading_2.py +++ b/greentest/test_threading_2.py @@ -22,8 +22,12 @@ threading.Thread.is_alive = threading.Thread.isAlive if not hasattr(threading.Thread, 'daemon'): threading.Thread.daemon = property(threading.Thread.isDaemon, threading.Thread.setDaemon) -if not hasattr(threading._Condition, 'notify_all'): - threading._Condition.notify_all = threading._Condition.notifyAll +try: + if not hasattr(threading.Condition, 'notify_all'): + threading.Condition.notify_all = threading.Condition.notifyAll +except AttributeError: + if not hasattr(threading._Condition, 'notify_all'): + threading._Condition.notify_all = threading._Condition.notifyAll ''' six.exec_(setup_) @@ -33,8 +37,8 @@ setup_5 = '\n'.join(' %s' % line for line in setup_.split('\n')) -import test.test_support -from test.test_support import verbose +import test_support +from test_support import verbose import random import re import sys @@ -298,7 +302,11 @@ def test_finalize_runnning_thread(self): import subprocess rc = subprocess.call([sys.executable, "-c", """if 1: %s - import ctypes, sys, time, thread + import ctypes, sys, time + try: + import thread + except ImportError: + import _thread as thread # This lock is used as a simple event variable. ready = thread.allocate_lock() @@ -347,6 +355,9 @@ def child(): stderr=subprocess.PIPE) stdout, stderr = p.communicate() stdout = stdout.strip() + if six.PY3: + stdout = stdout.decode() + stderr = stderr.decode() assert re.match('^Woke up, sleep function is: <.*?sleep.*?>$', stdout), repr(stdout) stderr = re.sub(r"^\[\d+ refs\]", "", stderr, re.MULTILINE).strip() self.assertEqual(stderr, "") @@ -419,8 +430,8 @@ def joiningfunc(mainthread): import subprocess p = subprocess.Popen([sys.executable, "-c", script], stdout=subprocess.PIPE) rc = p.wait() - data = p.stdout.read().replace('\r', '') - self.assertEqual(data, "end of main\nend of thread\n") + data = p.stdout.read().replace(six.b('\r'), six.b('')) + self.assertEqual(data, six.b("end of main\nend of thread\n")) self.failIf(rc == 2, "interpreter was blocked") self.failUnless(rc == 0, "Unexpected error") @@ -539,7 +550,7 @@ class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): def main(): - test.test_support.run_unittest(LockTests, RLockTests, EventTests, + test_support.run_unittest(LockTests, RLockTests, EventTests, ConditionAsRLockTests, ConditionTests, SemaphoreTests, BoundedSemaphoreTests, ThreadTests,