[pypy-commit] pypy unroll-if-alt: merged default.
alex_gaynor
noreply at buildbot.pypy.org
Wed Sep 14 20:26:16 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: unroll-if-alt
Changeset: r47271:a16809d0db00
Date: 2011-09-14 11:17 -0400
http://bitbucket.org/pypy/pypy/changeset/a16809d0db00/
Log: merged default.
diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py
--- a/lib-python/2.7/ssl.py
+++ b/lib-python/2.7/ssl.py
@@ -62,7 +62,6 @@
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
from _ssl import SSLError
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
-from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
from _ssl import RAND_status, RAND_egd, RAND_add
from _ssl import \
SSL_ERROR_ZERO_RETURN, \
@@ -74,6 +73,18 @@
SSL_ERROR_WANT_CONNECT, \
SSL_ERROR_EOF, \
SSL_ERROR_INVALID_ERROR_CODE
+from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
+_PROTOCOL_NAMES = {
+ PROTOCOL_TLSv1: "TLSv1",
+ PROTOCOL_SSLv23: "SSLv23",
+ PROTOCOL_SSLv3: "SSLv3",
+}
+try:
+ from _ssl import PROTOCOL_SSLv2
+except ImportError:
+ pass
+else:
+ _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
from socket import socket, _fileobject, _delegate_methods, error as socket_error
from socket import getnameinfo as _getnameinfo
@@ -408,16 +419,7 @@
return DER_cert_to_PEM_cert(dercert)
def get_protocol_name(protocol_code):
- if protocol_code == PROTOCOL_TLSv1:
- return "TLSv1"
- elif protocol_code == PROTOCOL_SSLv23:
- return "SSLv23"
- elif protocol_code == PROTOCOL_SSLv2:
- return "SSLv2"
- elif protocol_code == PROTOCOL_SSLv3:
- return "SSLv3"
- else:
- return "<unknown>"
+ return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
# a replacement for the old socket.ssl function
diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py
--- a/lib-python/2.7/test/test_ssl.py
+++ b/lib-python/2.7/test/test_ssl.py
@@ -58,32 +58,35 @@
# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
def skip_if_broken_ubuntu_ssl(func):
- # We need to access the lower-level wrapper in order to create an
- # implicit SSL context without trying to connect or listen.
- try:
- import _ssl
- except ImportError:
- # The returned function won't get executed, just ignore the error
- pass
- @functools.wraps(func)
- def f(*args, **kwargs):
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ # We need to access the lower-level wrapper in order to create an
+ # implicit SSL context without trying to connect or listen.
try:
- s = socket.socket(socket.AF_INET)
- _ssl.sslwrap(s._sock, 0, None, None,
- ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
- except ssl.SSLError as e:
- if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
- platform.linux_distribution() == ('debian', 'squeeze/sid', '')
- and 'Invalid SSL protocol variant specified' in str(e)):
- raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
- return func(*args, **kwargs)
- return f
+ import _ssl
+ except ImportError:
+ # The returned function won't get executed, just ignore the error
+ pass
+ @functools.wraps(func)
+ def f(*args, **kwargs):
+ try:
+ s = socket.socket(socket.AF_INET)
+ _ssl.sslwrap(s._sock, 0, None, None,
+ ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
+ except ssl.SSLError as e:
+ if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
+ platform.linux_distribution() == ('debian', 'squeeze/sid', '')
+ and 'Invalid SSL protocol variant specified' in str(e)):
+ raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
+ return func(*args, **kwargs)
+ return f
+ else:
+ return func
class BasicSocketTests(unittest.TestCase):
def test_constants(self):
- ssl.PROTOCOL_SSLv2
+ #ssl.PROTOCOL_SSLv2
ssl.PROTOCOL_SSLv23
ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLSv1
@@ -964,7 +967,8 @@
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
@@ -976,7 +980,8 @@
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
diff --git a/lib-python/modified-2.7/ssl.py b/lib-python/modified-2.7/ssl.py
--- a/lib-python/modified-2.7/ssl.py
+++ b/lib-python/modified-2.7/ssl.py
@@ -62,7 +62,6 @@
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
from _ssl import SSLError
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
-from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
from _ssl import RAND_status, RAND_egd, RAND_add
from _ssl import \
SSL_ERROR_ZERO_RETURN, \
@@ -74,6 +73,18 @@
SSL_ERROR_WANT_CONNECT, \
SSL_ERROR_EOF, \
SSL_ERROR_INVALID_ERROR_CODE
+from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
+_PROTOCOL_NAMES = {
+ PROTOCOL_TLSv1: "TLSv1",
+ PROTOCOL_SSLv23: "SSLv23",
+ PROTOCOL_SSLv3: "SSLv3",
+}
+try:
+ from _ssl import PROTOCOL_SSLv2
+except ImportError:
+ pass
+else:
+ _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
from socket import socket, _fileobject, error as socket_error
from socket import getnameinfo as _getnameinfo
@@ -400,16 +411,7 @@
return DER_cert_to_PEM_cert(dercert)
def get_protocol_name(protocol_code):
- if protocol_code == PROTOCOL_TLSv1:
- return "TLSv1"
- elif protocol_code == PROTOCOL_SSLv23:
- return "SSLv23"
- elif protocol_code == PROTOCOL_SSLv2:
- return "SSLv2"
- elif protocol_code == PROTOCOL_SSLv3:
- return "SSLv3"
- else:
- return "<unknown>"
+ return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')
# a replacement for the old socket.ssl function
diff --git a/lib-python/modified-2.7/test/test_ssl.py b/lib-python/modified-2.7/test/test_ssl.py
--- a/lib-python/modified-2.7/test/test_ssl.py
+++ b/lib-python/modified-2.7/test/test_ssl.py
@@ -58,32 +58,35 @@
# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
def skip_if_broken_ubuntu_ssl(func):
- # We need to access the lower-level wrapper in order to create an
- # implicit SSL context without trying to connect or listen.
- try:
- import _ssl
- except ImportError:
- # The returned function won't get executed, just ignore the error
- pass
- @functools.wraps(func)
- def f(*args, **kwargs):
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ # We need to access the lower-level wrapper in order to create an
+ # implicit SSL context without trying to connect or listen.
try:
- s = socket.socket(socket.AF_INET)
- _ssl.sslwrap(s._sock, 0, None, None,
- ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
- except ssl.SSLError as e:
- if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
- platform.linux_distribution() == ('debian', 'squeeze/sid', '')
- and 'Invalid SSL protocol variant specified' in str(e)):
- raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
- return func(*args, **kwargs)
- return f
+ import _ssl
+ except ImportError:
+ # The returned function won't get executed, just ignore the error
+ pass
+ @functools.wraps(func)
+ def f(*args, **kwargs):
+ try:
+ s = socket.socket(socket.AF_INET)
+ _ssl.sslwrap(s._sock, 0, None, None,
+ ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
+ except ssl.SSLError as e:
+ if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
+ platform.linux_distribution() == ('debian', 'squeeze/sid', '')
+ and 'Invalid SSL protocol variant specified' in str(e)):
+ raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
+ return func(*args, **kwargs)
+ return f
+ else:
+ return func
class BasicSocketTests(unittest.TestCase):
def test_constants(self):
- ssl.PROTOCOL_SSLv2
+ #ssl.PROTOCOL_SSLv2
ssl.PROTOCOL_SSLv23
ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLSv1
@@ -966,7 +969,8 @@
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
@@ -978,7 +982,8 @@
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
- try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
+ if hasattr(ssl, 'PROTOCOL_SSLv2'):
+ try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -48,23 +48,23 @@
def switch(self, *args):
"Switch execution to this greenlet, optionally passing the values "
"given as argument(s). Returns the value passed when switching back."
- return self.__switch(_continulet.switch, args)
+ return self.__switch('switch', args)
def throw(self, typ=GreenletExit, val=None, tb=None):
"raise exception in greenlet, return value passed when switching back"
- return self.__switch(_continulet.throw, typ, val, tb)
+ return self.__switch('throw', typ, val, tb)
- def __switch(target, unbound_method, *args):
+ def __switch(target, methodname, *args):
current = getcurrent()
#
while not target:
if not target.__started:
- if unbound_method != _continulet.throw:
+ if methodname == 'switch':
greenlet_func = _greenlet_start
else:
greenlet_func = _greenlet_throw
_continulet.__init__(target, greenlet_func, *args)
- unbound_method = _continulet.switch
+ methodname = 'switch'
args = ()
target.__started = True
break
@@ -75,22 +75,8 @@
target = target.parent
#
try:
- if current.__main:
- if target.__main:
- # switch from main to main
- if unbound_method == _continulet.throw:
- raise args[0], args[1], args[2]
- (args,) = args
- else:
- # enter from main to target
- args = unbound_method(target, *args)
- else:
- if target.__main:
- # leave to go to target=main
- args = unbound_method(current, *args)
- else:
- # switch from non-main to non-main
- args = unbound_method(current, *args, to=target)
+ unbound_method = getattr(_continulet, methodname)
+ args = unbound_method(current, *args, to=target)
except GreenletExit, e:
args = (e,)
finally:
diff --git a/lib_pypy/stackless.py b/lib_pypy/stackless.py
--- a/lib_pypy/stackless.py
+++ b/lib_pypy/stackless.py
@@ -7,19 +7,12 @@
import traceback
import _continuation
-from functools import partial
class TaskletExit(Exception):
pass
CoroutineExit = TaskletExit
-class GWrap(_continuation.continulet):
- """This is just a wrapper around continulet to allow
- to stick additional attributes to a continulet.
- To be more concrete, we need a backreference to
- the coroutine object"""
-
class coroutine(object):
"we can't have continulet as a base, because continulets can't be rebound"
@@ -42,12 +35,10 @@
arguments *argl, **argd
"""
if self._frame is None or not self._frame.is_pending():
-
- def _func(c, *args, **kwargs):
- return func(*args, **kwargs)
-
- run = partial(_func, *argl, **argd)
- self._frame = frame = GWrap(run)
+ def run(c):
+ _tls.current_coroutine = self
+ return func(*argl, **argd)
+ self._frame = frame = _continuation.continulet(run)
else:
raise ValueError("cannot bind a bound coroutine")
@@ -58,16 +49,18 @@
None is returned
"""
current = _getcurrent()
- current._jump_to(self)
-
- def _jump_to(self, coroutine):
- _tls.current_coroutine = coroutine
- self._frame.switch(to=coroutine._frame)
+ try:
+ current._frame.switch(to=self._frame)
+ finally:
+ _tls.current_coroutine = current
def kill(self):
"""coro.kill() : kill coroutine coro"""
- _tls.current_coroutine = self
- self._frame.throw(CoroutineExit)
+ current = _getcurrent()
+ try:
+ current._frame.throw(CoroutineExit, to=self._frame)
+ finally:
+ _tls.current_coroutine = current
def _is_alive(self):
if self._frame is None:
@@ -78,10 +71,7 @@
def getcurrent():
"""coroutine.getcurrent() -> the currently running coroutine"""
- try:
- return _getcurrent()
- except AttributeError:
- return _maincoro
+ return _getcurrent()
getcurrent = staticmethod(getcurrent)
def __reduce__(self):
@@ -109,13 +99,10 @@
# create the main coroutine for this thread
_tls.current_coroutine = None
main_coroutine = coroutine()
- main_coroutine.bind(lambda x:x)
+ typ = _continuation.continulet
+ main_coroutine._frame = typ.__new__(typ)
_tls.main_coroutine = main_coroutine
_tls.current_coroutine = main_coroutine
- return main_coroutine
-
-
-_maincoro = _coroutine_create_main()
from collections import deque
@@ -161,10 +148,10 @@
_last_task = next
assert not next.blocked
if next is not current:
- try:
+ #try:
next.switch()
- except CoroutineExit:
- raise TaskletExit
+ #except CoroutineExit: --- they are the same anyway
+ # raise TaskletExit
return current
def set_schedule_callback(callback):
@@ -459,6 +446,7 @@
def _func():
try:
try:
+ coroutine.switch(back)
func(*argl, **argd)
except TaskletExit:
pass
@@ -468,6 +456,8 @@
self.func = None
coroutine.bind(self, _func)
+ back = _getcurrent()
+ coroutine.switch(self)
self.alive = True
_scheduler_append(self)
return self
diff --git a/pypy/doc/stackless.rst b/pypy/doc/stackless.rst
--- a/pypy/doc/stackless.rst
+++ b/pypy/doc/stackless.rst
@@ -66,7 +66,7 @@
In practice, in PyPy, you cannot change the ``f_back`` of an abitrary
frame, but only of frames stored in ``continulets``.
-Continulets are internally implemented using stacklets. Stacklets are a
+Continulets are internally implemented using stacklets_. Stacklets are a
bit more primitive (they are really one-shot continuations), but that
idea only works in C, not in Python. The basic idea of continulets is
to have at any point in time a complete valid stack; this is important
@@ -280,6 +280,24 @@
to use other interfaces like genlets and greenlets.)
+Stacklets
++++++++++
+
+Continulets are internally implemented using stacklets, which is the
+generic RPython-level building block for "one-shot continuations". For
+more information about them please see the documentation in the C source
+at `pypy/translator/c/src/stacklet/stacklet.h`_.
+
+The module ``pypy.rlib.rstacklet`` is a thin wrapper around the above
+functions. The key point is that new() and switch() always return a
+fresh stacklet handle (or an empty one), and switch() additionally
+consumes one. It makes no sense to have code in which the returned
+handle is ignored, or used more than once. Note that ``stacklet.c`` is
+written assuming that the user knows that, and so no additional checking
+occurs; this can easily lead to obscure crashes if you don't use a
+wrapper like PyPy's '_continuation' module.
+
+
Theory of composability
+++++++++++++++++++++++
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -48,6 +48,7 @@
return frame
@staticmethod
+ @jit.unroll_safe # should usually loop 0 times, very rarely more than once
def getnextframe_nohidden(frame):
frame = frame.f_backref()
while frame and frame.hide():
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -614,8 +614,8 @@
return self.get_builtin().getdict(space)
def fget_f_back(self, space):
- f_backref = ExecutionContext.getnextframe_nohidden(self)
- return self.space.wrap(f_backref)
+ f_back = ExecutionContext.getnextframe_nohidden(self)
+ return self.space.wrap(f_back)
def fget_f_lasti(self, space):
return self.space.wrap(self.last_instr)
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3277,7 +3277,27 @@
return n
self.meta_interp(f, [10], repeat=3)
-
+
+ def test_jit_merge_point_with_pbc(self):
+ driver = JitDriver(greens = [], reds = ['x'])
+
+ class A(object):
+ def __init__(self, x):
+ self.x = x
+ def _freeze_(self):
+ return True
+ pbc = A(1)
+
+ def main(x):
+ return f(x, pbc)
+
+ def f(x, pbc):
+ while x > 0:
+ driver.jit_merge_point(x = x)
+ x -= pbc.x
+ return x
+
+ self.meta_interp(main, [10])
def test_look_inside_iff_const(self):
@look_inside_iff(lambda arg: isconstant(arg))
diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -43,16 +43,29 @@
raise getmemoryerror(self.space)
def switch(self, w_to):
+ sthread = self.sthread
+ if sthread is not None and sthread.is_empty_handle(self.h):
+ start_state.clear()
+ raise geterror(self.space, "continulet already finished")
to = self.space.interp_w(W_Continulet, w_to, can_be_None=True)
+ if to is not None and to.sthread is None:
+ to = None
+ if sthread is None: # if self is non-initialized:
+ if to is not None: # if we are given a 'to'
+ self = to # then just use it and ignore 'self'
+ sthread = self.sthread
+ to = None
+ else:
+ return get_result() # else: no-op
if to is not None:
- if to.sthread is None:
+ if to.sthread is not sthread:
start_state.clear()
- raise geterror(self.space, "continulet not initialized yet")
+ raise geterror(self.space, "cross-thread double switch")
if self is to: # double-switch to myself: no-op
return get_result()
- if self.sthread is None:
- start_state.clear()
- raise geterror(self.space, "continulet not initialized yet")
+ if sthread.is_empty_handle(to.h):
+ start_state.clear()
+ raise geterror(self.space, "continulet already finished")
ec = self.check_sthread()
#
start_state.origin = self
@@ -63,14 +76,8 @@
# double switch: the final destination is to.h
start_state.destination = to
#
- h = start_state.destination.h
- sthread = self.sthread
- if sthread.is_empty_handle(h):
- start_state.clear()
- raise geterror(self.space, "continulet already finished")
- #
try:
- do_switch(sthread, h)
+ do_switch(sthread, start_state.destination.h)
except MemoryError:
start_state.clear()
raise getmemoryerror(self.space)
diff --git a/pypy/module/_continuation/test/test_stacklet.py b/pypy/module/_continuation/test/test_stacklet.py
--- a/pypy/module/_continuation/test/test_stacklet.py
+++ b/pypy/module/_continuation/test/test_stacklet.py
@@ -135,12 +135,6 @@
e = raises(error, c.switch)
assert str(e.value) == "continulet already finished"
- def test_not_initialized_yet(self):
- from _continuation import continulet, error
- c = continulet.__new__(continulet)
- e = raises(error, c.switch)
- assert str(e.value) == "continulet not initialized yet"
-
def test_go_depth2(self):
from _continuation import continulet
#
@@ -254,6 +248,15 @@
res = c_upper.switch('D')
assert res == 'E'
+ def test_switch_not_initialized(self):
+ from _continuation import continulet
+ c0 = continulet.__new__(continulet)
+ res = c0.switch()
+ assert res is None
+ res = c0.switch(123)
+ assert res == 123
+ raises(ValueError, c0.throw, ValueError)
+
def test_exception_with_switch_depth2(self):
from _continuation import continulet
#
@@ -499,16 +502,31 @@
assert res == 'z'
raises(TypeError, c1.switch, to=c2) # "can't send non-None value"
- def test_switch2_not_initialized_yet(self):
- from _continuation import continulet, error
+ def test_switch2_not_initialized(self):
+ from _continuation import continulet
+ c0 = continulet.__new__(continulet)
+ c0bis = continulet.__new__(continulet)
+ res = c0.switch(123, to=c0)
+ assert res == 123
+ res = c0.switch(123, to=c0bis)
+ assert res == 123
+ raises(ValueError, c0.throw, ValueError, to=c0)
+ raises(ValueError, c0.throw, ValueError, to=c0bis)
#
def f1(c1):
- not_reachable
- #
+ c1.switch('a')
+ raises(ValueError, c1.switch, 'b')
+ raises(KeyError, c1.switch, 'c')
+ return 'd'
c1 = continulet(f1)
- c2 = continulet.__new__(continulet)
- e = raises(error, c1.switch, to=c2)
- assert str(e.value) == "continulet not initialized yet"
+ res = c0.switch(to=c1)
+ assert res == 'a'
+ res = c1.switch(to=c0)
+ assert res == 'b'
+ res = c1.throw(ValueError, to=c0)
+ assert res == 'c'
+ res = c0.throw(KeyError, to=c1)
+ assert res == 'd'
def test_switch2_already_finished(self):
from _continuation import continulet, error
@@ -643,6 +661,16 @@
assert res == "done"
main()
+ def test_bug_finish_with_already_finished_stacklet(self):
+ from _continuation import continulet, error
+ # make an already-finished continulet
+ c1 = continulet(lambda x: x)
+ c1.switch()
+ # make another continulet
+ c2 = continulet(lambda x: x)
+ # this switch is forbidden, because it causes a crash when c2 finishes
+ raises(error, c1.switch, to=c2)
+
def test_various_depths(self):
skip("may fail on top of CPython")
# run it from test_translated, but not while being actually translated
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -52,7 +52,8 @@
constants["CERT_OPTIONAL"] = PY_SSL_CERT_OPTIONAL
constants["CERT_REQUIRED"] = PY_SSL_CERT_REQUIRED
-constants["PROTOCOL_SSLv2"] = PY_SSL_VERSION_SSL2
+if not OPENSSL_NO_SSL2:
+ constants["PROTOCOL_SSLv2"] = PY_SSL_VERSION_SSL2
constants["PROTOCOL_SSLv3"] = PY_SSL_VERSION_SSL3
constants["PROTOCOL_SSLv23"] = PY_SSL_VERSION_SSL23
constants["PROTOCOL_TLSv1"] = PY_SSL_VERSION_TLS1
@@ -673,7 +674,7 @@
method = libssl_TLSv1_method()
elif protocol == PY_SSL_VERSION_SSL3:
method = libssl_SSLv3_method()
- elif protocol == PY_SSL_VERSION_SSL2:
+ elif protocol == PY_SSL_VERSION_SSL2 and not OPENSSL_NO_SSL2:
method = libssl_SSLv2_method()
elif protocol == PY_SSL_VERSION_SSL23:
method = libssl_SSLv23_method()
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -508,7 +508,7 @@
return space._type_issubtype(w_sub, w_type)
def isinstance(space, w_inst, w_type):
- return space._type_isinstance(w_inst, w_type)
+ return space.wrap(space._type_isinstance(w_inst, w_type))
def issubtype_allow_override(space, w_sub, w_type):
w_check = space.lookup(w_type, "__subclasscheck__")
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -370,8 +370,8 @@
newdata = []
for i in range(len(list_w)):
w_s = list_w[i]
- if not (space.is_true(space.isinstance(w_s, space.w_str)) or
- space.is_true(space.isinstance(w_s, space.w_bytearray))):
+ if not (space.isinstance_w(w_s, space.w_str) or
+ space.isinstance_w(w_s, space.w_bytearray)):
raise operationerrfmt(
space.w_TypeError,
"sequence item %d: expected string, %s "
diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py
--- a/pypy/objspace/std/complextype.py
+++ b/pypy/objspace/std/complextype.py
@@ -127,8 +127,8 @@
and space.is_w(space.type(w_real), space.w_complex)):
return w_real
- if space.is_true(space.isinstance(w_real, space.w_str)) or \
- space.is_true(space.isinstance(w_real, space.w_unicode)):
+ if space.isinstance_w(w_real, space.w_str) or \
+ space.isinstance_w(w_real, space.w_unicode):
# a string argument
if not noarg2:
raise OperationError(space.w_TypeError,
@@ -203,8 +203,8 @@
return (w_complex.realval, w_complex.imagval)
#
# Check that it is not a string (on which space.float() would succeed).
- if (space.is_true(space.isinstance(w_complex, space.w_str)) or
- space.is_true(space.isinstance(w_complex, space.w_unicode))):
+ if (space.isinstance_w(w_complex, space.w_str) or
+ space.isinstance_w(w_complex, space.w_unicode)):
raise operationerrfmt(space.w_TypeError,
"complex number expected, got '%s'",
space.type(w_complex).getname(space))
diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -32,14 +32,14 @@
if space.is_w(w_floattype, space.w_float):
return w_obj
value = space.float_w(w_obj)
- elif space.is_true(space.isinstance(w_value, space.w_str)):
+ elif space.isinstance_w(w_value, space.w_str):
strvalue = space.str_w(w_value)
try:
value = string_to_float(strvalue)
except ParseStringError, e:
raise OperationError(space.w_ValueError,
space.wrap(e.msg))
- elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+ elif space.isinstance_w(w_value, space.w_unicode):
if space.config.objspace.std.withropeunicode:
from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
else:
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -425,15 +425,15 @@
space.wrap("operand does not support "
"unary str"))
w_result = space.get_and_call_function(w_impl, w_value)
- if space.is_true(space.isinstance(w_result,
- space.w_unicode)):
+ if space.isinstance_w(w_result,
+ space.w_unicode):
raise NeedUnicodeFormattingError
return space.str_w(w_result)
def fmt_s(self, w_value):
space = self.space
- got_unicode = space.is_true(space.isinstance(w_value,
- space.w_unicode))
+ got_unicode = space.isinstance_w(w_value,
+ space.w_unicode)
if not do_unicode:
if got_unicode:
raise NeedUnicodeFormattingError
@@ -452,13 +452,13 @@
def fmt_c(self, w_value):
self.prec = -1 # just because
space = self.space
- if space.is_true(space.isinstance(w_value, space.w_str)):
+ if space.isinstance_w(w_value, space.w_str):
s = space.str_w(w_value)
if len(s) != 1:
raise OperationError(space.w_TypeError,
space.wrap("%c requires int or char"))
self.std_wp(s)
- elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+ elif space.isinstance_w(w_value, space.w_unicode):
if not do_unicode:
raise NeedUnicodeFormattingError
ustr = space.unicode_w(w_value)
@@ -520,15 +520,15 @@
return space.wrap(result)
def mod_format(space, w_format, w_values, do_unicode=False):
- if space.is_true(space.isinstance(w_values, space.w_tuple)):
+ if space.isinstance_w(w_values, space.w_tuple):
values_w = space.fixedview(w_values)
return format(space, w_format, values_w, None, do_unicode)
else:
# we check directly for dict to avoid obscure checking
# in simplest case
- if space.is_true(space.isinstance(w_values, space.w_dict)) or \
+ if space.isinstance_w(w_values, space.w_dict) or \
(space.lookup(w_values, '__getitem__') and
- not space.is_true(space.isinstance(w_values, space.w_basestring))):
+ not space.isinstance_w(w_values, space.w_basestring)):
return format(space, w_format, [w_values], w_values, do_unicode)
else:
return format(space, w_format, [w_values], None, do_unicode)
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -99,10 +99,10 @@
if type(w_value) is W_IntObject:
value = w_value.intval
ok = True
- elif space.is_true(space.isinstance(w_value, space.w_str)):
+ elif space.isinstance_w(w_value, space.w_str):
value, w_longval = string_to_int_or_long(space, space.str_w(w_value))
ok = True
- elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+ elif space.isinstance_w(w_value, space.w_unicode):
if space.config.objspace.std.withropeunicode:
from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
else:
@@ -145,7 +145,7 @@
else:
base = space.int_w(w_base)
- if space.is_true(space.isinstance(w_value, space.w_unicode)):
+ if space.isinstance_w(w_value, space.w_unicode):
if space.config.objspace.std.withropeunicode:
from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
else:
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -72,6 +72,10 @@
w_seqiter.index += 1
return w_item
+# XXX __length_hint__()
+##def len__SeqIter(space, w_seqiter):
+## return w_seqiter.getlength(space)
+
def iter__FastTupleIter(space, w_seqiter):
return w_seqiter
@@ -89,6 +93,10 @@
w_seqiter.index = index + 1
return w_item
+# XXX __length_hint__()
+##def len__FastTupleIter(space, w_seqiter):
+## return w_seqiter.getlength(space)
+
def iter__FastListIter(space, w_seqiter):
return w_seqiter
@@ -106,6 +114,10 @@
w_seqiter.index = index + 1
return w_item
+# XXX __length_hint__()
+##def len__FastListIter(space, w_seqiter):
+## return w_seqiter.getlength(space)
+
def iter__ReverseSeqIter(space, w_seqiter):
return w_seqiter
@@ -123,5 +135,20 @@
raise OperationError(space.w_StopIteration, space.w_None)
return w_item
+# XXX __length_hint__()
+##def len__ReverseSeqIter(space, w_seqiter):
+## if w_seqiter.w_seq is None:
+## return space.wrap(0)
+## index = w_seqiter.index+1
+## w_length = space.len(w_seqiter.w_seq)
+## # if length of sequence is less than index :exhaust iterator
+## if space.is_true(space.gt(space.wrap(w_seqiter.index), w_length)):
+## w_len = space.wrap(0)
+## w_seqiter.w_seq = None
+## else:
+## w_len =space.wrap(index)
+## if space.is_true(space.lt(w_len,space.wrap(0))):
+## w_len = space.wrap(0)
+## return w_len
register_all(vars())
diff --git a/pypy/objspace/std/longtype.py b/pypy/objspace/std/longtype.py
--- a/pypy/objspace/std/longtype.py
+++ b/pypy/objspace/std/longtype.py
@@ -24,9 +24,9 @@
return w_value
elif type(w_value) is W_LongObject:
return newbigint(space, w_longtype, w_value.num)
- elif space.is_true(space.isinstance(w_value, space.w_str)):
+ elif space.isinstance_w(w_value, space.w_str):
return string_to_w_long(space, w_longtype, space.str_w(w_value))
- elif space.is_true(space.isinstance(w_value, space.w_unicode)):
+ elif space.isinstance_w(w_value, space.w_unicode):
if space.config.objspace.std.withropeunicode:
from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
else:
@@ -51,7 +51,7 @@
else:
base = space.int_w(w_base)
- if space.is_true(space.isinstance(w_value, space.w_unicode)):
+ if space.isinstance_w(w_value, space.w_unicode):
from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
s = unicode_to_decimal_w(space, w_value)
else:
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -350,7 +350,7 @@
SLOTS_STARTING_FROM = 3
-class BaseMapdictObject: # slightly evil to make it inherit from W_Root
+class BaseMapdictObject:
_mixin_ = True
def _init_empty(self, map):
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -571,5 +571,8 @@
def _type_isinstance(self, w_inst, w_type):
if isinstance(w_type, W_TypeObject):
- return self.wrap(self.type(w_inst).issubtype(w_type))
+ return self.type(w_inst).issubtype(w_type)
raise OperationError(self.w_TypeError, self.wrap("need type object"))
+
+ def isinstance_w(space, w_inst, w_type):
+ return space._type_isinstance(w_inst, w_type)
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -292,8 +292,8 @@
l = []
for i in range(size):
w_s = list_w[i]
- if not space.is_true(space.isinstance(w_s, space.w_str)):
- if space.is_true(space.isinstance(w_s, space.w_unicode)):
+ if not space.isinstance_w(w_s, space.w_str):
+ if space.isinstance_w(w_s, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
return space.call_method(w_u, "join", space.newlist(list_w))
raise operationerrfmt(
@@ -556,7 +556,7 @@
W_RopeObject.EMPTY, w_start,
w_end, True)
for w_suffix in space.fixedview(w_suffixes):
- if space.is_true(space.isinstance(w_suffix, space.w_unicode)):
+ if space.isinstance_w(w_suffix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
return space.call_method(w_u, "endswith", w_suffixes, w_start,
w_end)
@@ -576,7 +576,7 @@
(self, _, start, end) = _convert_idx_params(space, w_self, W_RopeObject.EMPTY,
w_start, w_end, True)
for w_prefix in space.fixedview(w_prefixes):
- if space.is_true(space.isinstance(w_prefix, space.w_unicode)):
+ if space.isinstance_w(w_prefix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
return space.call_method(w_u, "startswith", w_prefixes, w_start,
w_end)
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -29,7 +29,7 @@
assert isinstance(w_str, W_RopeObject)
encoding = getdefaultencoding(space)
w_retval = decode_string(space, w_str, encoding, "strict")
- if not space.is_true(space.isinstance(w_retval, space.w_unicode)):
+ if not space.isinstance_w(w_retval, space.w_unicode):
raise operationerrfmt(
space.w_TypeError,
"decoder did not return an unicode object (type '%s')",
@@ -254,7 +254,7 @@
if isinstance(w_item, W_RopeUnicodeObject):
# shortcut for performane
item = w_item._node
- elif space.is_true(space.isinstance(w_item, space.w_str)):
+ elif space.isinstance_w(w_item, space.w_str):
item = unicode_from_string(space, w_item)._node
else:
msg = 'sequence item %d: expected string or Unicode'
@@ -828,14 +828,14 @@
else:
if space.is_w(w_newval, space.w_None):
continue
- elif space.is_true(space.isinstance(w_newval, space.w_int)):
+ elif space.isinstance_w(w_newval, space.w_int):
newval = space.int_w(w_newval)
if newval < 0 or newval > maxunicode:
raise OperationError(
space.w_TypeError,
space.wrap("character mapping must be in range(0x%x)" % (maxunicode + 1,)))
result.append(rope.rope_from_unichar(unichr(newval)))
- elif space.is_true(space.isinstance(w_newval, space.w_unicode)):
+ elif space.isinstance_w(w_newval, space.w_unicode):
result.append(ropeunicode_w(space, w_newval))
else:
raise OperationError(
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -132,7 +132,7 @@
w_obj.setdata = make_setdata_from_w_iterable(space, w_iterable)
def _convert_set_to_frozenset(space, w_obj):
- if space.is_true(space.isinstance(w_obj, space.w_set)):
+ if space.isinstance_w(w_obj, space.w_set):
return W_FrozensetObject(space,
make_setdata_from_w_iterable(space, w_obj))
else:
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -364,8 +364,8 @@
reslen = len(self) * (size - 1)
for i in range(size):
w_s = list_w[i]
- if not space.is_true(space.isinstance(w_s, space.w_str)):
- if space.is_true(space.isinstance(w_s, space.w_unicode)):
+ if not space.isinstance_w(w_s, space.w_str):
+ if space.isinstance_w(w_s, space.w_unicode):
# we need to rebuild w_list here, because the original
# w_list might be an iterable which we already consumed
w_list = space.newlist(list_w)
@@ -646,7 +646,7 @@
space.wrap(''), w_start,
w_end, True)
for w_suffix in space.fixedview(w_suffixes):
- if space.is_true(space.isinstance(w_suffix, space.w_unicode)):
+ if space.isinstance_w(w_suffix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
return space.call_method(w_u, "endswith", w_suffixes, w_start,
w_end)
@@ -665,7 +665,7 @@
(u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''),
w_start, w_end, True)
for w_prefix in space.fixedview(w_prefixes):
- if space.is_true(space.isinstance(w_prefix, space.w_unicode)):
+ if space.isinstance_w(w_prefix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
return space.call_method(w_u, "startswith", w_prefixes, w_start,
w_end)
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -508,15 +508,15 @@
# type name. That's a hack, so we're allowed to use a different
# hack...
if ('__module__' in w_self.dict_w and
- space.is_true(space.isinstance(w_self.getdictvalue(space, '__module__'),
- space.w_str))):
+ space.isinstance_w(w_self.getdictvalue(space, '__module__'),
+ space.w_str)):
return w_self.getdictvalue(space, '__module__')
return space.wrap('__builtin__')
def get_module_type_name(w_self):
space = w_self.space
w_mod = w_self.get_module()
- if not space.is_true(space.isinstance(w_mod, space.w_str)):
+ if not space.isinstance_w(w_mod, space.w_str):
mod = '__builtin__'
else:
mod = space.str_w(w_mod)
@@ -850,7 +850,7 @@
not space.is_w(w_newtype, space.w_type)):
w_type.w_bltin_new = w_newfunc
w_newobject = space.call_obj_args(w_newfunc, w_type, __args__)
- call_init = space.is_true(space.isinstance(w_newobject, w_type))
+ call_init = space.isinstance_w(w_newobject, w_type)
# maybe invoke the __init__ of the type
if call_init:
@@ -876,7 +876,7 @@
def repr__Type(space, w_obj):
w_mod = w_obj.get_module()
- if not space.is_true(space.isinstance(w_mod, space.w_str)):
+ if not space.isinstance_w(w_mod, space.w_str):
mod = None
else:
mod = space.str_w(w_mod)
diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py
--- a/pypy/objspace/std/typetype.py
+++ b/pypy/objspace/std/typetype.py
@@ -110,7 +110,7 @@
if not w_type.is_heaptype():
raise operationerrfmt(space.w_TypeError,
"can't set %s.__bases__", w_type.name)
- if not space.is_true(space.isinstance(w_value, space.w_tuple)):
+ if not space.isinstance_w(w_value, space.w_tuple):
raise operationerrfmt(space.w_TypeError,
"can only assign tuple to %s.__bases__, not %s",
w_type.name,
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -900,14 +900,14 @@
else:
if space.is_w(w_newval, space.w_None):
continue
- elif space.is_true(space.isinstance(w_newval, space.w_int)):
+ elif space.isinstance_w(w_newval, space.w_int):
newval = space.int_w(w_newval)
if newval < 0 or newval > maxunicode:
raise OperationError(
space.w_TypeError,
space.wrap("character mapping must be in range(0x%x)" % (maxunicode + 1,)))
result.append(unichr(newval))
- elif space.is_true(space.isinstance(w_newval, space.w_unicode)):
+ elif space.isinstance_w(w_newval, space.w_unicode):
result.append(space.unicode_w(w_newval))
else:
raise OperationError(
diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py
--- a/pypy/objspace/std/unicodetype.py
+++ b/pypy/objspace/std/unicodetype.py
@@ -251,7 +251,7 @@
w_errors = space.wrap(errors)
w_restuple = space.call_function(w_encoder, w_object, w_errors)
w_retval = space.getitem(w_restuple, space.wrap(0))
- if not space.is_true(space.isinstance(w_retval, space.w_str)):
+ if not space.isinstance_w(w_retval, space.w_str):
raise operationerrfmt(space.w_TypeError,
"encoder did not return an string object (type '%s')",
space.type(w_retval).getname(space))
@@ -286,7 +286,7 @@
def unicode_from_encoded_object(space, w_obj, encoding, errors):
w_retval = decode_object(space, w_obj, encoding, errors)
- if not space.is_true(space.isinstance(w_retval, space.w_unicode)):
+ if not space.isinstance_w(w_retval, space.w_unicode):
raise operationerrfmt(space.w_TypeError,
"decoder did not return an unicode object (type '%s')",
space.type(w_retval).getname(space))
@@ -309,7 +309,7 @@
w_res = space.get_and_call_function(w_unicode_method, w_obj)
else:
w_res = space.str(w_obj)
- if space.is_true(space.isinstance(w_res, space.w_unicode)):
+ if space.isinstance_w(w_res, space.w_unicode):
return w_res
return unicode_from_encoded_object(space, w_res, None, "strict")
@@ -346,7 +346,7 @@
# convoluted logic for the case when unicode subclass has a __unicode__
# method, we need to call this method
if (space.is_w(space.type(w_obj), space.w_unicode) or
- (space.is_true(space.isinstance(w_obj, space.w_unicode)) and
+ (space.isinstance_w(w_obj, space.w_unicode) and
space.findattr(w_obj, space.wrap('__unicode__')) is None)):
if encoding is not None or errors is not None:
raise OperationError(space.w_TypeError,
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -62,6 +62,8 @@
"OPENSSL_VERSION_NUMBER")
SSLEAY_VERSION = rffi_platform.DefinedConstantString(
"SSLEAY_VERSION", "SSLeay_version(SSLEAY_VERSION)")
+ OPENSSL_NO_SSL2 = rffi_platform.DefinedConstantInteger(
+ "OPENSSL_NO_SSL2")
SSL_FILETYPE_PEM = rffi_platform.ConstantInteger("SSL_FILETYPE_PEM")
SSL_OP_ALL = rffi_platform.ConstantInteger("SSL_OP_ALL")
SSL_VERIFY_NONE = rffi_platform.ConstantInteger("SSL_VERIFY_NONE")
diff --git a/pypy/rlib/rstacklet.py b/pypy/rlib/rstacklet.py
--- a/pypy/rlib/rstacklet.py
+++ b/pypy/rlib/rstacklet.py
@@ -1,6 +1,8 @@
from pypy.rlib import _rffi_stacklet as _c
from pypy.rpython.lltypesystem import lltype, llmemory
+DEBUG = False
+
class StackletThread(object):
@@ -10,15 +12,30 @@
if not self._thrd:
raise MemoryError
self._thrd_deleter = StackletThreadDeleter(self._thrd)
+ if DEBUG:
+ assert debug.sthread is None, "multithread debug support missing"
+ debug.sthread = self
def new(self, callback, arg=llmemory.NULL):
- return self._gcrootfinder.new(self, callback, arg)
+ if DEBUG:
+ callback = _debug_wrapper(callback)
+ h = self._gcrootfinder.new(self, callback, arg)
+ if DEBUG:
+ debug.add(h)
+ return h
new._annspecialcase_ = 'specialize:arg(1)'
def switch(self, stacklet):
- return self._gcrootfinder.switch(self, stacklet)
+ if DEBUG:
+ debug.remove(stacklet)
+ h = self._gcrootfinder.switch(self, stacklet)
+ if DEBUG:
+ debug.add(h)
+ return h
def destroy(self, stacklet):
+ if DEBUG:
+ debug.remove(stacklet)
self._gcrootfinder.destroy(self, stacklet)
def is_empty_handle(self, stacklet):
@@ -56,3 +73,34 @@
None, None, ['__doc__'])
return module.gcrootfinder
_getgcrootfinder._annspecialcase_ = 'specialize:memo'
+
+
+class StackletDebugError(Exception):
+ pass
+
+class Debug(object):
+ def __init__(self):
+ self.sthread = None
+ self.active = []
+ def _freeze_(self):
+ self.__init__()
+ return False
+ def add(self, h):
+ if not self.sthread.is_empty_handle(h):
+ self.active.append(h)
+ def remove(self, h):
+ try:
+ i = self.active.index(h)
+ except ValueError:
+ raise StackletDebugError
+ del self.active[i]
+debug = Debug()
+
+def _debug_wrapper(callback):
+ def wrapper(h, arg):
+ debug.add(h)
+ h = callback(h, arg)
+ debug.remove(h)
+ return h
+ return wrapper
+_debug_wrapper._annspecialcase_ = 'specialize:memo'
diff --git a/pypy/rpython/memory/gctransform/asmgcroot.py b/pypy/rpython/memory/gctransform/asmgcroot.py
--- a/pypy/rpython/memory/gctransform/asmgcroot.py
+++ b/pypy/rpython/memory/gctransform/asmgcroot.py
@@ -636,7 +636,8 @@
ASM_FRAMEDATA_HEAD_PTR],
lltype.Signed,
sandboxsafe=True,
- _nowrapper=True)
+ _nowrapper=True,
+ random_effects_on_gcobjs=True)
c_asm_stackwalk = Constant(pypy_asm_stackwalk,
lltype.typeOf(pypy_asm_stackwalk))
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -41,7 +41,7 @@
seen)
def analyze_external_call(self, op, seen=None):
funcobj = op.args[0].value._obj
- if funcobj._name == 'pypy_asm_stackwalk':
+ if getattr(funcobj, 'random_effects_on_gcobjs', False):
return True
return graphanalyze.GraphAnalyzer.analyze_external_call(self, op,
seen)
diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py
--- a/pypy/rpython/test/test_rbuilder.py
+++ b/pypy/rpython/test/test_rbuilder.py
@@ -101,6 +101,23 @@
res = self.interpret(func, [1])
assert res
+ def test_unicode_builder_or_none(self):
+ def g(s):
+ if s:
+ s.append(u"3")
+ return bool(s)
+
+ def func(i):
+ if i:
+ s = UnicodeBuilder()
+ else:
+ s = None
+ return g(s)
+ res = self.interpret(func, [0])
+ assert not res
+ res = self.interpret(func, [1])
+ assert res
+
class TestLLtype(BaseTestStringBuilder, LLRtypeMixin):
pass
diff --git a/pypy/translator/unsimplify.py b/pypy/translator/unsimplify.py
--- a/pypy/translator/unsimplify.py
+++ b/pypy/translator/unsimplify.py
@@ -97,6 +97,23 @@
if _forcelink is not None:
assert index == 0
linkargs = list(_forcelink)
+ for v in varmap:
+ if v not in linkargs:
+ # 'v' was not specified by _forcelink, but we found out that
+ # we need it! Hack: if it is 'concretetype is lltype.Void'
+ # then it's ok to recreate its value in the target block.
+ # If not, then we have a problem :-)
+ from pypy.rpython.lltypesystem import lltype
+ assert v.concretetype is lltype.Void
+ c = Constant(None, lltype.Void)
+ w = varmap[v]
+ newop = SpaceOperation('same_as', [c], w)
+ i = 0
+ while i < len(moved_operations):
+ if w in moved_operations[i].args:
+ break
+ i += 1
+ moved_operations.insert(i, newop)
else:
linkargs = varmap.keys()
newblock = Block([get_new_name(v) for v in linkargs])
More information about the pypy-commit
mailing list