Skip to content

Commit

Permalink
Refs gevent#38, fixed ssl.py and the rest failing tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
fantix committed Dec 10, 2012
1 parent a8ac793 commit 5a67290
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 37 deletions.
2 changes: 2 additions & 0 deletions gevent/core.ppyx
Expand Up @@ -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):
Expand Down
12 changes: 8 additions & 4 deletions gevent/socket.py
Expand Up @@ -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__()
Expand Down Expand Up @@ -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__[:]:
Expand Down
73 changes: 54 additions & 19 deletions gevent/ssl.py
Expand Up @@ -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',
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()

Expand All @@ -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."""
Expand Down
13 changes: 10 additions & 3 deletions greentest/lock_tests.py
Expand Up @@ -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():
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion greentest/test__ssl.py
Expand Up @@ -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

Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions greentest/test__threading_vs_settrace.py
Expand Up @@ -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)
27 changes: 19 additions & 8 deletions greentest/test_threading_2.py
Expand Up @@ -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_)
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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, "")
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 5a67290

Please sign in to comment.