[pypy-commit] pypy py3k: merge default
pjenvey
noreply at buildbot.pypy.org
Tue Sep 10 00:30:35 CEST 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r66884:c1f9cb9361f6
Date: 2013-09-09 14:18 -0700
http://bitbucket.org/pypy/pypy/changeset/c1f9cb9361f6/
Log: merge default
diff too long, truncating to 2000 out of 7230 lines
diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py
--- a/lib-python/2.7/uuid.py
+++ b/lib-python/2.7/uuid.py
@@ -44,6 +44,8 @@
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
"""
+import struct
+
__author__ = 'Ka-Ping Yee <ping at zesty.ca>'
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
@@ -125,25 +127,38 @@
overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'.
"""
- if [hex, bytes, bytes_le, fields, int].count(None) != 4:
- raise TypeError('need one of hex, bytes, bytes_le, fields, or int')
if hex is not None:
+ if (bytes is not None or bytes_le is not None or fields is not None
+ or int is not None):
+ raise TypeError('if the hex argument is given, bytes, bytes_le, fields,'
+ ' and int need to be None')
hex = hex.replace('urn:', '').replace('uuid:', '')
hex = hex.strip('{}').replace('-', '')
if len(hex) != 32:
raise ValueError('badly formed hexadecimal UUID string')
int = long(hex, 16)
- if bytes_le is not None:
+ elif bytes_le is not None:
+ if bytes is not None or fields is not None or int is not None:
+ raise TypeError('if the bytes_le argument is given, bytes, fields,'
+ ' and int need to be None')
if len(bytes_le) != 16:
raise ValueError('bytes_le is not a 16-char string')
bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] +
bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] +
bytes_le[8:])
- if bytes is not None:
+ int = (struct.unpack('>Q', bytes[:8])[0] << 64 |
+ struct.unpack('>Q', bytes[8:])[0])
+ elif bytes is not None:
+ if fields is not None or int is not None:
+ raise TypeError('if the bytes argument is given, fields'
+ ' and int need to be None')
if len(bytes) != 16:
raise ValueError('bytes is not a 16-char string')
- int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
- if fields is not None:
+ int = (struct.unpack('>Q', bytes[:8])[0] << 64 |
+ struct.unpack('>Q', bytes[8:])[0])
+ elif fields is not None:
+ if int is not None:
+ raise TypeError('if the fields argument is given, int needs to be None')
if len(fields) != 6:
raise ValueError('fields is not a 6-tuple')
(time_low, time_mid, time_hi_version,
@@ -163,9 +178,12 @@
clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
int = ((time_low << 96L) | (time_mid << 80L) |
(time_hi_version << 64L) | (clock_seq << 48L) | node)
- if int is not None:
+ elif int is not None:
if not 0 <= int < 1<<128L:
raise ValueError('int is out of range (need a 128-bit value)')
+ else:
+ raise TypeError('one of hex, bytes, bytes_le, fields,'
+ ' or int need to be not None')
if version is not None:
if not 1 <= version <= 5:
raise ValueError('illegal version number')
@@ -175,7 +193,7 @@
# Set the version number.
int &= ~(0xf000 << 64L)
int |= version << 76L
- self.__dict__['int'] = int
+ object.__setattr__(self, 'int', int)
def __cmp__(self, other):
if isinstance(other, UUID):
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -1,6 +1,9 @@
"""Reimplementation of the standard extension module '_curses' using cffi."""
import sys
+if sys.platform == 'win32':
+ #This module does not exist in windows
+ raise ImportError('No module named _curses')
from functools import wraps
from cffi import FFI
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1241,7 +1241,10 @@
if cvt is not None:
param = cvt(param)
- param = adapt(param)
+ try:
+ param = adapt(param)
+ except:
+ pass # And use previous value
if param is None:
rc = _lib.sqlite3_bind_null(self._statement, idx)
diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py
--- a/lib_pypy/_tkinter/__init__.py
+++ b/lib_pypy/_tkinter/__init__.py
@@ -22,6 +22,7 @@
READABLE = tklib.TCL_READABLE
WRITABLE = tklib.TCL_WRITABLE
EXCEPTION = tklib.TCL_EXCEPTION
+DONT_WAIT = tklib.TCL_DONT_WAIT
def create(screenName=None, baseName=None, className=None,
interactive=False, wantobjects=False, wantTk=True,
diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
--- a/lib_pypy/_tkinter/app.py
+++ b/lib_pypy/_tkinter/app.py
@@ -4,7 +4,23 @@
from . import TclError
from .tclobj import TclObject, FromObj, AsObj, TypeCache
+import contextlib
import sys
+import threading
+import time
+
+
+class _DummyLock(object):
+ "A lock-like object that does not do anything"
+ def acquire(self):
+ pass
+ def release(self):
+ pass
+ def __enter__(self):
+ pass
+ def __exit__(self, *exc):
+ pass
+
def varname_converter(input):
if isinstance(input, TclObject):
@@ -37,18 +53,19 @@
def PythonCmd(clientData, interp, argc, argv):
self = tkffi.from_handle(clientData)
assert self.app.interp == interp
- try:
- args = [tkffi.string(arg).decode('utf-8')
- for arg in argv[1:argc]]
- result = self.func(*args)
- obj = AsObj(result)
- tklib.Tcl_SetObjResult(interp, obj)
- except:
- self.app.errorInCmd = True
- self.app.exc_info = sys.exc_info()
- return tklib.TCL_ERROR
- else:
- return tklib.TCL_OK
+ with self.app._tcl_lock_released():
+ try:
+ args = [tkffi.string(arg).decode('utf-8')
+ for arg in argv[1:argc]]
+ result = self.func(*args)
+ obj = AsObj(result)
+ tklib.Tcl_SetObjResult(interp, obj)
+ except:
+ self.app.errorInCmd = True
+ self.app.exc_info = sys.exc_info()
+ return tklib.TCL_ERROR
+ else:
+ return tklib.TCL_OK
@tkffi.callback("Tcl_CmdDeleteProc")
def PythonCmdDelete(clientData):
@@ -59,6 +76,8 @@
class TkApp(object):
+ _busywaitinterval = 0.02 # 20ms.
+
def __new__(cls, screenName, className,
interactive, wantobjects, wantTk, sync, use):
if not wantobjects:
@@ -74,6 +93,12 @@
self.quitMainLoop = False
self.errorInCmd = False
+ if not self.threaded:
+ # TCL is not thread-safe, calls needs to be serialized.
+ self._tcl_lock = threading.Lock()
+ else:
+ self._tcl_lock = _DummyLock()
+
self._typeCache = TypeCache()
self._commands = {}
@@ -136,6 +161,13 @@
if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
raise RuntimeError("Calling Tcl from different appartment")
+ @contextlib.contextmanager
+ def _tcl_lock_released(self):
+ "Context manager to temporarily release the tcl lock."
+ self._tcl_lock.release()
+ yield
+ self._tcl_lock.acquire()
+
def loadtk(self):
# We want to guard against calling Tk_Init() multiple times
err = tklib.Tcl_Eval(self.interp, b"info exists tk_version")
@@ -162,22 +194,25 @@
flags=tklib.TCL_LEAVE_ERR_MSG
if global_only:
flags |= tklib.TCL_GLOBAL_ONLY
- res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
- if not res:
- self.raiseTclError()
- assert self._wantobjects
- return FromObj(self, res)
+ with self._tcl_lock:
+ res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
+ if not res:
+ self.raiseTclError()
+ assert self._wantobjects
+ return FromObj(self, res)
def _setvar(self, name1, value, global_only=False):
name1 = varname_converter(name1)
+ # XXX Acquire tcl lock???
newval = AsObj(value)
flags=tklib.TCL_LEAVE_ERR_MSG
if global_only:
flags |= tklib.TCL_GLOBAL_ONLY
- res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
- newval, flags)
- if not res:
- self.raiseTclError()
+ with self._tcl_lock:
+ res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
+ newval, flags)
+ if not res:
+ self.raiseTclError()
def _unsetvar(self, name1, name2=None, global_only=False):
name1 = varname_converter(name1)
@@ -186,9 +221,10 @@
flags=tklib.TCL_LEAVE_ERR_MSG
if global_only:
flags |= tklib.TCL_GLOBAL_ONLY
- res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
- if res == tklib.TCL_ERROR:
- self.raiseTclError()
+ with self._tcl_lock:
+ res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
def getvar(self, name1, name2=None):
return self._var_invoke(self._getvar, name1, name2)
@@ -222,9 +258,10 @@
if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
raise NotImplementedError("Call from another thread")
- res = tklib.Tcl_CreateCommand(
- self.interp, cmdName.encode('utf-8'), _CommandData.PythonCmd,
- clientData, _CommandData.PythonCmdDelete)
+ with self._tcl_lock:
+ res = tklib.Tcl_CreateCommand(
+ self.interp, cmdName.encode('utf-8'), _CommandData.PythonCmd,
+ clientData, _CommandData.PythonCmdDelete)
if not res:
raise TclError("can't create Tcl command")
@@ -232,7 +269,8 @@
if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
raise NotImplementedError("Call from another thread")
- res = tklib.Tcl_DeleteCommand(self.interp, cmdName.encode('utf-8'))
+ with self._tcl_lock:
+ res = tklib.Tcl_DeleteCommand(self.interp, cmdName.encode('utf-8'))
if res == -1:
raise TclError("can't delete Tcl command")
@@ -259,11 +297,12 @@
tklib.Tcl_IncrRefCount(obj)
objects[i] = obj
- res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
- if res == tklib.TCL_ERROR:
- self.raiseTclError()
- else:
- result = self._callResult()
+ with self._tcl_lock:
+ res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ else:
+ result = self._callResult()
finally:
for obj in objects:
if obj:
@@ -283,19 +322,21 @@
def eval(self, script):
self._check_tcl_appartment()
- res = tklib.Tcl_Eval(self.interp, script.encode('utf-8'))
- if res == tklib.TCL_ERROR:
- self.raiseTclError()
- result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
- return result.decode('utf-8')
+ with self._tcl_lock:
+ res = tklib.Tcl_Eval(self.interp, script.encode('utf-8'))
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+ return result.decode('utf-8')
def evalfile(self, filename):
self._check_tcl_appartment()
- res = tklib.Tcl_EvalFile(self.interp, filename.encode('utf-8'))
- if res == tklib.TCL_ERROR:
- self.raiseTclError()
- result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
- return result.decode('utf-8')
+ with self._tcl_lock:
+ res = tklib.Tcl_EvalFile(self.interp, filename.encode('utf-8'))
+ if res == tklib.TCL_ERROR:
+ self.raiseTclError()
+ result = tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+ return result.decode('utf-8')
def split(self, arg):
if isinstance(arg, tuple):
@@ -381,7 +422,10 @@
if self.threaded:
result = tklib.Tcl_DoOneEvent(0)
else:
- raise NotImplementedError("TCL configured without threads")
+ with self._tcl_lock:
+ result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT)
+ if result == 0:
+ time.sleep(self._busywaitinterval)
if result < 0:
break
diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py
--- a/lib_pypy/_tkinter/tklib.py
+++ b/lib_pypy/_tkinter/tklib.py
@@ -1,6 +1,7 @@
# C bindings with libtcl and libtk.
from cffi import FFI
+import sys
tkffi = FFI()
@@ -18,6 +19,8 @@
#define TCL_EVAL_DIRECT ...
#define TCL_EVAL_GLOBAL ...
+#define TCL_DONT_WAIT ...
+
typedef unsigned short Tcl_UniChar;
typedef ... Tcl_Interp;
typedef ...* Tcl_ThreadId;
@@ -102,6 +105,17 @@
int Tk_GetNumMainWindows();
""")
+# XXX find a better way to detect paths
+# XXX pick up CPPFLAGS and LDFLAGS and add to these paths?
+if sys.platform.startswith("openbsd"):
+ incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include']
+ linklibs = ['tk85', 'tcl85']
+ libdirs = ['/usr/local/lib', '/usr/X11R6/lib']
+else:
+ incdirs=['/usr/include/tcl']
+ linklibs=['tcl', 'tk']
+ libdirs = []
+
tklib = tkffi.verify("""
#include <tcl.h>
#include <tk.h>
@@ -109,6 +123,7 @@
char *get_tk_version() { return TK_VERSION; }
char *get_tcl_version() { return TCL_VERSION; }
""",
-include_dirs=['/usr/include/tcl'],
-libraries=['tcl', 'tk'],
+include_dirs=incdirs,
+libraries=linklibs,
+library_dirs = libdirs
)
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,5 +4,5 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "0.7"
-__version_info__ = (0, 7)
+__version__ = "0.7.2"
+__version_info__ = (0, 7, 2)
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -54,7 +54,8 @@
# _cffi_backend.so compiled.
import _cffi_backend as backend
from . import __version__
- assert backend.__version__ == __version__
+ assert (backend.__version__ == __version__ or
+ backend.__version__ == __version__[:3])
# (If you insist you can also try to pass the option
# 'backend=backend_ctypes.CTypesBackend()', but don't
# rely on it! It's probably not going to work well.)
diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py
--- a/lib_pypy/cffi/commontypes.py
+++ b/lib_pypy/cffi/commontypes.py
@@ -30,7 +30,9 @@
elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
result = model.PrimitiveType(result)
else:
- assert commontype != result
+ if commontype == result:
+ raise api.FFIError("Unsupported type: %r. Please file a bug "
+ "if you think it should be." % (commontype,))
result = resolve_common_type(result) # recursively
assert isinstance(result, model.BaseTypeByIdentity)
_CACHE[commontype] = result
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -290,13 +290,26 @@
# assume a primitive type. get it from .names, but reduce
# synonyms to a single chosen combination
names = list(type.names)
- if names == ['signed'] or names == ['unsigned']:
- names.append('int')
- if names[0] == 'signed' and names != ['signed', 'char']:
- names.pop(0)
- if (len(names) > 1 and names[-1] == 'int'
- and names != ['unsigned', 'int']):
- names.pop()
+ if names != ['signed', 'char']: # keep this unmodified
+ prefixes = {}
+ while names:
+ name = names[0]
+ if name in ('short', 'long', 'signed', 'unsigned'):
+ prefixes[name] = prefixes.get(name, 0) + 1
+ del names[0]
+ else:
+ break
+ # ignore the 'signed' prefix below, and reorder the others
+ newnames = []
+ for prefix in ('unsigned', 'short', 'long'):
+ for i in range(prefixes.get(prefix, 0)):
+ newnames.append(prefix)
+ if not names:
+ names = ['int'] # implicitly
+ if names == ['int']: # but kill it if 'short' or 'long'
+ if 'short' in prefixes or 'long' in prefixes:
+ names = []
+ names = newnames + names
ident = ' '.join(names)
if ident == 'void':
return model.void_type
@@ -500,8 +513,8 @@
self._partial_length = True
return None
#
- raise api.FFIError("unsupported non-constant or "
- "not immediately constant expression")
+ raise api.FFIError("unsupported expression: expected a "
+ "simple numeric constant")
def _build_enum_type(self, explicit_name, decls):
if decls is not None:
diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py
--- a/lib_pypy/cffi/vengine_gen.py
+++ b/lib_pypy/cffi/vengine_gen.py
@@ -61,7 +61,9 @@
def load_library(self):
# import it with the CFFI backend
backend = self.ffi._backend
- module = backend.load_library(self.verifier.modulefilename)
+ # needs to make a path that contains '/', on Posix
+ filename = os.path.join(os.curdir, self.verifier.modulefilename)
+ module = backend.load_library(filename)
#
# call loading_gen_struct() to get the struct layout inferred by
# the C compiler
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -130,11 +130,6 @@
pypy_optiondescription = OptionDescription("objspace", "Object Space Options", [
- OptionDescription("opcodes", "opcodes to enable in the interpreter", [
- BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()",
- default=False),
- ]),
-
OptionDescription("usemodules", "Which Modules should be used", [
BoolOption(modname, "use module %s" % (modname, ),
default=modname in default_modules,
@@ -253,9 +248,6 @@
BoolOption("optimized_int_add",
"special case the addition of two integers in BINARY_ADD",
default=False),
- BoolOption("optimized_comparison_op",
- "special case the comparison of integers",
- default=False),
BoolOption("optimized_list_getitem",
"special case the 'list[integer]' expressions",
default=False),
@@ -301,7 +293,6 @@
# all the good optimizations for PyPy should be listed here
if level in ['2', '3', 'jit']:
- config.objspace.opcodes.suggest(CALL_METHOD=True)
config.objspace.std.suggest(withmethodcache=True)
config.objspace.std.suggest(withprebuiltchar=True)
config.objspace.std.suggest(builtinshortcut=True)
diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Enable a pair of bytecodes that speed up method calls.
-See ``pypy.interpreter.callmethod`` for a description.
-
-The goal is to avoid creating the bound method object in the common
-case. So far, this only works for calls with no keyword, no ``*arg``
-and no ``**arg`` but it would be easy to extend.
-
-For more information, see the section in `Standard Interpreter Optimizations`_.
-
-.. _`Standard Interpreter Optimizations`: ../interpreter-optimizations.html#lookup-method-call-method
diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.opcodes.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-.. intentionally empty
diff --git a/pypy/doc/interpreter-optimizations.rst b/pypy/doc/interpreter-optimizations.rst
--- a/pypy/doc/interpreter-optimizations.rst
+++ b/pypy/doc/interpreter-optimizations.rst
@@ -198,9 +198,6 @@
if it is not None, then it is considered to be an additional first
argument in the call to the *im_func* object from the stack.
-You can enable this feature with the :config:`objspace.opcodes.CALL_METHOD`
-option.
-
.. more here?
Overall Effects
diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py
--- a/pypy/doc/tool/makecontributor.py
+++ b/pypy/doc/tool/makecontributor.py
@@ -60,6 +60,11 @@
'Roberto De Ioris': ['roberto at mrspurr'],
'Sven Hager': ['hager'],
'Tomo Cocoa': ['cocoatomo'],
+ 'Romain Guillebert': ['rguillebert', 'rguillbert', 'romain', 'Guillebert Romain'],
+ 'Ronan Lamy': ['ronan'],
+ 'Edd Barrett': ['edd'],
+ 'Manuel Jacob': ['mjacob'],
+ 'Rami Chowdhury': ['necaris'],
}
alias_map = {}
@@ -80,7 +85,8 @@
if not match:
return set()
ignore_words = ['around', 'consulting', 'yesterday', 'for a bit', 'thanks',
- 'in-progress', 'bits of', 'even a little', 'floating',]
+ 'in-progress', 'bits of', 'even a little', 'floating',
+ 'a bit', 'reviewing']
sep_words = ['and', ';', '+', '/', 'with special by']
nicknames = match.group(1)
for word in ignore_words:
@@ -119,7 +125,7 @@
## print '%5d %s' % (n, name)
## else:
## print name
-
+
items = authors_count.items()
items.sort(key=operator.itemgetter(1), reverse=True)
for name, n in items:
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -5,6 +5,11 @@
.. this is a revision shortly after release-2.1-beta
.. startrev: 4eb52818e7c0
+.. branch: sanitise_bytecode_dispatch
+Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython
+magic. There is no functional change, though the removal of dead code leads
+to many fewer tests to execute.
+
.. branch: fastjson
Fast json decoder written in RPython, about 3-4x faster than the pure Python
decoder which comes with the stdlib
@@ -75,3 +80,18 @@
.. branch: reflex-support
.. branch: numpypy-inplace-op
.. branch: rewritten-loop-logging
+.. branch: no-release-gil
+
+.. branch: nobold-backtrace
+Work on improving UnionError messages and stack trace displays.
+
+.. branch: improve-errors-again
+More improvements and refactorings of error messages.
+
+.. branch: improve-errors-again2
+Unbreak tests in rlib.
+
+.. branch: less-stringly-ops
+Use subclasses of SpaceOperation instead of SpaceOperator objects.
+Random cleanups in flowspace.
+
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -1074,9 +1074,8 @@
return self._call_has_no_star_args(call) and not call.keywords
def _optimize_method_call(self, call):
- if not self.space.config.objspace.opcodes.CALL_METHOD or \
- not self._call_has_no_star_args(call) or \
- not isinstance(call.func, ast.Attribute):
+ if not self._call_has_no_star_args(call) or \
+ not isinstance(call.func, ast.Attribute):
return False
attr_lookup = call.func
assert isinstance(attr_lookup, ast.Attribute)
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -77,13 +77,12 @@
raise NotImplementedError("only for interp-level user subclasses "
"from typedef.py")
- def getname(self, space, default=u'?'):
+ def getname(self, space):
try:
return space.unicode_w(space.getattr(self, space.wrap('__name__')))
except OperationError, e:
- if (e.match(space, space.w_TypeError) or
- e.match(space, space.w_AttributeError)):
- return default
+ if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError):
+ return '?'
raise
def getaddrstring(self, space):
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -275,8 +275,10 @@
tuple(self.co_cellvars))
def exec_host_bytecode(self, w_globals, w_locals):
- from pypy.interpreter.pyframe import CPythonFrame
- frame = CPythonFrame(self.space, self, w_globals, None)
+ if sys.version_info < (2, 7):
+ raise Exception("PyPy no longer supports Python 2.6 or lower")
+ from pypy.interpreter.pyframe import PyFrame
+ frame = self.space.FrameClass(self.space, self, w_globals, None)
frame.setdictscope(w_locals)
return frame.run()
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -52,7 +52,7 @@
def __init__(self, space, code, w_globals, outer_func):
if not we_are_translated():
- assert type(self) in (space.FrameClass, CPythonFrame), (
+ assert type(self) == space.FrameClass, (
"use space.FrameClass(), not directly PyFrame()")
self = hint(self, access_directly=True, fresh_virtualizable=True)
assert isinstance(code, pycode.PyCode)
@@ -677,17 +677,6 @@
return space.wrap(self.builtin is not space.builtin)
return space.w_False
-class CPythonFrame(PyFrame):
- """
- Execution of host (CPython) opcodes.
- """
-
- bytecode_spec = host_bytecode_spec
- opcode_method_names = host_bytecode_spec.method_names
- opcodedesc = host_bytecode_spec.opcodedesc
- opdescmap = host_bytecode_spec.opdescmap
- HAVE_ARGUMENT = host_bytecode_spec.HAVE_ARGUMENT
-
# ____________________________________________________________
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -13,10 +13,8 @@
from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib import jit, rstackovf
from rpython.rlib.rarithmetic import r_uint, intmask
-from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.debug import check_nonneg
-from pypy.tool.stdlib_opcode import (bytecode_spec,
- unrolling_all_opcode_descs)
+from pypy.tool.stdlib_opcode import bytecode_spec
CANNOT_CATCH_MSG = ("catching classes that don't inherit from BaseException "
"is not allowed in 3.x")
@@ -44,34 +42,14 @@
return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)
-compare_dispatch_table = [
- "cmp_lt", # "<"
- "cmp_le", # "<="
- "cmp_eq", # "=="
- "cmp_ne", # "!="
- "cmp_gt", # ">"
- "cmp_ge", # ">="
- "cmp_in",
- "cmp_not_in",
- "cmp_is",
- "cmp_is_not",
- "cmp_exc_match",
- ]
-unrolling_compare_dispatch_table = unrolling_iterable(
- enumerate(compare_dispatch_table))
-
+opcodedesc = bytecode_spec.opcodedesc
+HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT
class __extend__(pyframe.PyFrame):
"""A PyFrame that knows about interpretation of standard Python opcodes
minus the ones related to nested scopes."""
- bytecode_spec = bytecode_spec
- opcode_method_names = bytecode_spec.method_names
- opcodedesc = bytecode_spec.opcodedesc
- opdescmap = bytecode_spec.opdescmap
- HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT
-
### opcode dispatch ###
def dispatch(self, pycode, next_instr, ec):
@@ -174,7 +152,7 @@
#print 'executing', self.last_instr, bytecode_spec.method_names[opcode]
next_instr += 1
- if opcode >= self.HAVE_ARGUMENT:
+ if opcode >= HAVE_ARGUMENT:
lo = ord(co_code[next_instr])
hi = ord(co_code[next_instr+1])
next_instr += 2
@@ -184,19 +162,18 @@
# note: the structure of the code here is such that it makes
# (after translation) a big "if/elif" chain, which is then
- # turned into a switch(). It starts here: even if the first
- # one is not an "if" but a "while" the effect is the same.
+ # turned into a switch().
- while opcode == self.opcodedesc.EXTENDED_ARG.index:
+ while opcode == opcodedesc.EXTENDED_ARG.index:
opcode = ord(co_code[next_instr])
- if opcode < self.HAVE_ARGUMENT:
+ if opcode < HAVE_ARGUMENT:
raise BytecodeCorruption
lo = ord(co_code[next_instr+1])
hi = ord(co_code[next_instr+2])
next_instr += 3
oparg = (oparg * 65536) | (hi * 256) | lo
- if opcode == self.opcodedesc.RETURN_VALUE.index:
+ if opcode == opcodedesc.RETURN_VALUE.index:
w_returnvalue = self.popvalue()
block = self.unrollstack(SReturnValue.kind)
if block is None:
@@ -206,8 +183,7 @@
unroller = SReturnValue(w_returnvalue)
next_instr = block.handle(self, unroller)
return next_instr # now inside a 'finally' block
-
- if opcode == self.opcodedesc.END_FINALLY.index:
+ elif opcode == opcodedesc.END_FINALLY.index:
unroller = self.end_finally()
if isinstance(unroller, SuspendedUnroller):
# go on unrolling the stack
@@ -219,49 +195,248 @@
else:
next_instr = block.handle(self, unroller)
return next_instr
-
- if opcode == self.opcodedesc.JUMP_ABSOLUTE.index:
+ elif opcode == opcodedesc.JUMP_ABSOLUTE.index:
return self.jump_absolute(oparg, ec)
-
- if we_are_translated():
- for opdesc in unrolling_all_opcode_descs:
- # static checks to skip this whole case if necessary
- if opdesc.bytecode_spec is not self.bytecode_spec:
- continue
- if not opdesc.is_enabled(space):
- continue
- if opdesc.methodname in (
- 'EXTENDED_ARG', 'RETURN_VALUE',
- 'END_FINALLY', 'JUMP_ABSOLUTE'):
- continue # opcodes implemented above
-
- # the following "if" is part of the big switch described
- # above.
- if opcode == opdesc.index:
- # dispatch to the opcode method
- meth = getattr(self, opdesc.methodname)
- res = meth(oparg, next_instr)
- # !! warning, for the annotator the next line is not
- # comparing an int and None - you can't do that.
- # Instead, it's constant-folded to either True or False
- if res is not None:
- next_instr = res
- break
- else:
- self.MISSING_OPCODE(oparg, next_instr)
-
- else: # when we are not translated, a list lookup is much faster
- methodname = self.opcode_method_names[opcode]
- try:
- meth = getattr(self, methodname)
- except AttributeError:
- raise BytecodeCorruption("unimplemented opcode, ofs=%d, "
- "code=%d, name=%s" %
- (self.last_instr, opcode,
- methodname))
- res = meth(oparg, next_instr)
- if res is not None:
- next_instr = res
+ elif opcode == opcodedesc.BREAK_LOOP.index:
+ next_instr = self.BREAK_LOOP(oparg, next_instr)
+ elif opcode == opcodedesc.CONTINUE_LOOP.index:
+ next_instr = self.CONTINUE_LOOP(oparg, next_instr)
+ elif opcode == opcodedesc.FOR_ITER.index:
+ next_instr = self.FOR_ITER(oparg, next_instr)
+ elif opcode == opcodedesc.JUMP_FORWARD.index:
+ next_instr = self.JUMP_FORWARD(oparg, next_instr)
+ elif opcode == opcodedesc.JUMP_IF_FALSE_OR_POP.index:
+ next_instr = self.JUMP_IF_FALSE_OR_POP(oparg, next_instr)
+ elif opcode == opcodedesc.JUMP_IF_NOT_DEBUG.index:
+ next_instr = self.JUMP_IF_NOT_DEBUG(oparg, next_instr)
+ elif opcode == opcodedesc.JUMP_IF_TRUE_OR_POP.index:
+ next_instr = self.JUMP_IF_TRUE_OR_POP(oparg, next_instr)
+ elif opcode == opcodedesc.POP_JUMP_IF_FALSE.index:
+ next_instr = self.POP_JUMP_IF_FALSE(oparg, next_instr)
+ elif opcode == opcodedesc.POP_JUMP_IF_TRUE.index:
+ next_instr = self.POP_JUMP_IF_TRUE(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_ADD.index:
+ self.BINARY_ADD(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_AND.index:
+ self.BINARY_AND(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_DIVIDE.index:
+ self.BINARY_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_FLOOR_DIVIDE.index:
+ self.BINARY_FLOOR_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_LSHIFT.index:
+ self.BINARY_LSHIFT(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_MODULO.index:
+ self.BINARY_MODULO(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_MULTIPLY.index:
+ self.BINARY_MULTIPLY(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_OR.index:
+ self.BINARY_OR(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_POWER.index:
+ self.BINARY_POWER(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_RSHIFT.index:
+ self.BINARY_RSHIFT(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_SUBSCR.index:
+ self.BINARY_SUBSCR(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_SUBTRACT.index:
+ self.BINARY_SUBTRACT(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_TRUE_DIVIDE.index:
+ self.BINARY_TRUE_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.BINARY_XOR.index:
+ self.BINARY_XOR(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_CLASS.index:
+ self.BUILD_CLASS(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_LIST.index:
+ self.BUILD_LIST(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_LIST_FROM_ARG.index:
+ self.BUILD_LIST_FROM_ARG(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_MAP.index:
+ self.BUILD_MAP(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_SET.index:
+ self.BUILD_SET(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_SLICE.index:
+ self.BUILD_SLICE(oparg, next_instr)
+ elif opcode == opcodedesc.BUILD_TUPLE.index:
+ self.BUILD_TUPLE(oparg, next_instr)
+ elif opcode == opcodedesc.CALL_FUNCTION.index:
+ self.CALL_FUNCTION(oparg, next_instr)
+ elif opcode == opcodedesc.CALL_FUNCTION_KW.index:
+ self.CALL_FUNCTION_KW(oparg, next_instr)
+ elif opcode == opcodedesc.CALL_FUNCTION_VAR.index:
+ self.CALL_FUNCTION_VAR(oparg, next_instr)
+ elif opcode == opcodedesc.CALL_FUNCTION_VAR_KW.index:
+ self.CALL_FUNCTION_VAR_KW(oparg, next_instr)
+ elif opcode == opcodedesc.CALL_METHOD.index:
+ self.CALL_METHOD(oparg, next_instr)
+ elif opcode == opcodedesc.COMPARE_OP.index:
+ self.COMPARE_OP(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_ATTR.index:
+ self.DELETE_ATTR(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_FAST.index:
+ self.DELETE_FAST(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_GLOBAL.index:
+ self.DELETE_GLOBAL(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_NAME.index:
+ self.DELETE_NAME(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_SLICE_0.index:
+ self.DELETE_SLICE_0(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_SLICE_1.index:
+ self.DELETE_SLICE_1(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_SLICE_2.index:
+ self.DELETE_SLICE_2(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_SLICE_3.index:
+ self.DELETE_SLICE_3(oparg, next_instr)
+ elif opcode == opcodedesc.DELETE_SUBSCR.index:
+ self.DELETE_SUBSCR(oparg, next_instr)
+ elif opcode == opcodedesc.DUP_TOP.index:
+ self.DUP_TOP(oparg, next_instr)
+ elif opcode == opcodedesc.DUP_TOPX.index:
+ self.DUP_TOPX(oparg, next_instr)
+ elif opcode == opcodedesc.EXEC_STMT.index:
+ self.EXEC_STMT(oparg, next_instr)
+ elif opcode == opcodedesc.GET_ITER.index:
+ self.GET_ITER(oparg, next_instr)
+ elif opcode == opcodedesc.IMPORT_FROM.index:
+ self.IMPORT_FROM(oparg, next_instr)
+ elif opcode == opcodedesc.IMPORT_NAME.index:
+ self.IMPORT_NAME(oparg, next_instr)
+ elif opcode == opcodedesc.IMPORT_STAR.index:
+ self.IMPORT_STAR(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_ADD.index:
+ self.INPLACE_ADD(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_AND.index:
+ self.INPLACE_AND(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_DIVIDE.index:
+ self.INPLACE_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_FLOOR_DIVIDE.index:
+ self.INPLACE_FLOOR_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_LSHIFT.index:
+ self.INPLACE_LSHIFT(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_MODULO.index:
+ self.INPLACE_MODULO(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_MULTIPLY.index:
+ self.INPLACE_MULTIPLY(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_OR.index:
+ self.INPLACE_OR(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_POWER.index:
+ self.INPLACE_POWER(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_RSHIFT.index:
+ self.INPLACE_RSHIFT(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_SUBTRACT.index:
+ self.INPLACE_SUBTRACT(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_TRUE_DIVIDE.index:
+ self.INPLACE_TRUE_DIVIDE(oparg, next_instr)
+ elif opcode == opcodedesc.INPLACE_XOR.index:
+ self.INPLACE_XOR(oparg, next_instr)
+ elif opcode == opcodedesc.LIST_APPEND.index:
+ self.LIST_APPEND(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_ATTR.index:
+ self.LOAD_ATTR(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_CLOSURE.index:
+ self.LOAD_CLOSURE(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_CONST.index:
+ self.LOAD_CONST(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_DEREF.index:
+ self.LOAD_DEREF(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_FAST.index:
+ self.LOAD_FAST(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_GLOBAL.index:
+ self.LOAD_GLOBAL(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_LOCALS.index:
+ self.LOAD_LOCALS(oparg, next_instr)
+ elif opcode == opcodedesc.LOAD_NAME.index:
+ self.LOAD_NAME(oparg, next_instr)
+ elif opcode == opcodedesc.LOOKUP_METHOD.index:
+ self.LOOKUP_METHOD(oparg, next_instr)
+ elif opcode == opcodedesc.MAKE_CLOSURE.index:
+ self.MAKE_CLOSURE(oparg, next_instr)
+ elif opcode == opcodedesc.MAKE_FUNCTION.index:
+ self.MAKE_FUNCTION(oparg, next_instr)
+ elif opcode == opcodedesc.MAP_ADD.index:
+ self.MAP_ADD(oparg, next_instr)
+ elif opcode == opcodedesc.NOP.index:
+ self.NOP(oparg, next_instr)
+ elif opcode == opcodedesc.POP_BLOCK.index:
+ self.POP_BLOCK(oparg, next_instr)
+ elif opcode == opcodedesc.POP_TOP.index:
+ self.POP_TOP(oparg, next_instr)
+ elif opcode == opcodedesc.PRINT_EXPR.index:
+ self.PRINT_EXPR(oparg, next_instr)
+ elif opcode == opcodedesc.PRINT_ITEM.index:
+ self.PRINT_ITEM(oparg, next_instr)
+ elif opcode == opcodedesc.PRINT_ITEM_TO.index:
+ self.PRINT_ITEM_TO(oparg, next_instr)
+ elif opcode == opcodedesc.PRINT_NEWLINE.index:
+ self.PRINT_NEWLINE(oparg, next_instr)
+ elif opcode == opcodedesc.PRINT_NEWLINE_TO.index:
+ self.PRINT_NEWLINE_TO(oparg, next_instr)
+ elif opcode == opcodedesc.RAISE_VARARGS.index:
+ self.RAISE_VARARGS(oparg, next_instr)
+ elif opcode == opcodedesc.ROT_FOUR.index:
+ self.ROT_FOUR(oparg, next_instr)
+ elif opcode == opcodedesc.ROT_THREE.index:
+ self.ROT_THREE(oparg, next_instr)
+ elif opcode == opcodedesc.ROT_TWO.index:
+ self.ROT_TWO(oparg, next_instr)
+ elif opcode == opcodedesc.SETUP_EXCEPT.index:
+ self.SETUP_EXCEPT(oparg, next_instr)
+ elif opcode == opcodedesc.SETUP_FINALLY.index:
+ self.SETUP_FINALLY(oparg, next_instr)
+ elif opcode == opcodedesc.SETUP_LOOP.index:
+ self.SETUP_LOOP(oparg, next_instr)
+ elif opcode == opcodedesc.SETUP_WITH.index:
+ self.SETUP_WITH(oparg, next_instr)
+ elif opcode == opcodedesc.SET_ADD.index:
+ self.SET_ADD(oparg, next_instr)
+ elif opcode == opcodedesc.SLICE_0.index:
+ self.SLICE_0(oparg, next_instr)
+ elif opcode == opcodedesc.SLICE_1.index:
+ self.SLICE_1(oparg, next_instr)
+ elif opcode == opcodedesc.SLICE_2.index:
+ self.SLICE_2(oparg, next_instr)
+ elif opcode == opcodedesc.SLICE_3.index:
+ self.SLICE_3(oparg, next_instr)
+ elif opcode == opcodedesc.STOP_CODE.index:
+ self.STOP_CODE(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_ATTR.index:
+ self.STORE_ATTR(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_DEREF.index:
+ self.STORE_DEREF(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_FAST.index:
+ self.STORE_FAST(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_GLOBAL.index:
+ self.STORE_GLOBAL(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_MAP.index:
+ self.STORE_MAP(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_NAME.index:
+ self.STORE_NAME(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_SLICE_0.index:
+ self.STORE_SLICE_0(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_SLICE_1.index:
+ self.STORE_SLICE_1(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_SLICE_2.index:
+ self.STORE_SLICE_2(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_SLICE_3.index:
+ self.STORE_SLICE_3(oparg, next_instr)
+ elif opcode == opcodedesc.STORE_SUBSCR.index:
+ self.STORE_SUBSCR(oparg, next_instr)
+ elif opcode == opcodedesc.UNARY_CONVERT.index:
+ self.UNARY_CONVERT(oparg, next_instr)
+ elif opcode == opcodedesc.UNARY_INVERT.index:
+ self.UNARY_INVERT(oparg, next_instr)
+ elif opcode == opcodedesc.UNARY_NEGATIVE.index:
+ self.UNARY_NEGATIVE(oparg, next_instr)
+ elif opcode == opcodedesc.UNARY_NOT.index:
+ self.UNARY_NOT(oparg, next_instr)
+ elif opcode == opcodedesc.UNARY_POSITIVE.index:
+ self.UNARY_POSITIVE(oparg, next_instr)
+ elif opcode == opcodedesc.UNPACK_SEQUENCE.index:
+ self.UNPACK_SEQUENCE(oparg, next_instr)
+ elif opcode == opcodedesc.WITH_CLEANUP.index:
+ self.WITH_CLEANUP(oparg, next_instr)
+ elif opcode == opcodedesc.YIELD_VALUE.index:
+ self.YIELD_VALUE(oparg, next_instr)
+ else:
+ self.MISSING_OPCODE(oparg, next_instr)
if jit.we_are_jitted():
return next_instr
@@ -714,36 +889,6 @@
self.pushvalue(w_value)
LOAD_ATTR._always_inline_ = True
- def cmp_lt(self, w_1, w_2):
- return self.space.lt(w_1, w_2)
-
- def cmp_le(self, w_1, w_2):
- return self.space.le(w_1, w_2)
-
- def cmp_eq(self, w_1, w_2):
- return self.space.eq(w_1, w_2)
-
- def cmp_ne(self, w_1, w_2):
- return self.space.ne(w_1, w_2)
-
- def cmp_gt(self, w_1, w_2):
- return self.space.gt(w_1, w_2)
-
- def cmp_ge(self, w_1, w_2):
- return self.space.ge(w_1, w_2)
-
- def cmp_in(self, w_1, w_2):
- return self.space.contains(w_2, w_1)
-
- def cmp_not_in(self, w_1, w_2):
- return self.space.not_(self.space.contains(w_2, w_1))
-
- def cmp_is(self, w_1, w_2):
- return self.space.is_(w_1, w_2)
-
- def cmp_is_not(self, w_1, w_2):
- return self.space.not_(self.space.is_(w_1, w_2))
-
@jit.unroll_safe
def cmp_exc_match(self, w_1, w_2):
space = self.space
@@ -760,11 +905,28 @@
def COMPARE_OP(self, testnum, next_instr):
w_2 = self.popvalue()
w_1 = self.popvalue()
- w_result = None
- for i, attr in unrolling_compare_dispatch_table:
- if i == testnum:
- w_result = getattr(self, attr)(w_1, w_2)
- break
+ if testnum == 0:
+ w_result = self.space.lt(w_1, w_2)
+ elif testnum == 1:
+ w_result = self.space.le(w_1, w_2)
+ elif testnum == 2:
+ w_result = self.space.eq(w_1, w_2)
+ elif testnum == 3:
+ w_result = self.space.ne(w_1, w_2)
+ elif testnum == 4:
+ w_result = self.space.gt(w_1, w_2)
+ elif testnum == 5:
+ w_result = self.space.ge(w_1, w_2)
+ elif testnum == 6:
+ w_result = self.space.contains(w_2, w_1)
+ elif testnum == 7:
+ w_result = self.space.not_(self.space.contains(w_2, w_1))
+ elif testnum == 8:
+ w_result = self.space.is_(w_1, w_2)
+ elif testnum == 9:
+ w_result = self.space.not_(self.space.is_(w_1, w_2))
+ elif testnum == 10:
+ w_result = self.cmp_exc_match(w_1, w_2)
else:
raise BytecodeCorruption("bad COMPARE_OP oparg")
self.pushvalue(w_result)
@@ -1095,49 +1257,6 @@
self.space.setitem(w_dict, w_key, w_value)
-class __extend__(pyframe.CPythonFrame):
-
- def JUMP_IF_FALSE(self, stepby, next_instr):
- w_cond = self.peekvalue()
- if not self.space.is_true(w_cond):
- next_instr += stepby
- return next_instr
-
- def JUMP_IF_TRUE(self, stepby, next_instr):
- w_cond = self.peekvalue()
- if self.space.is_true(w_cond):
- next_instr += stepby
- return next_instr
-
- def BUILD_MAP(self, itemcount, next_instr):
- if sys.version_info >= (2, 6):
- # We could pre-allocate a dict here
- # but for the moment this code is not translated.
- pass
- else:
- if itemcount != 0:
- raise BytecodeCorruption
- w_dict = self.space.newdict()
- self.pushvalue(w_dict)
-
- def STORE_MAP(self, zero, next_instr):
- if sys.version_info >= (2, 6):
- w_key = self.popvalue()
- w_value = self.popvalue()
- w_dict = self.peekvalue()
- self.space.setitem(w_dict, w_key, w_value)
- else:
- raise BytecodeCorruption
-
- def LIST_APPEND(self, oparg, next_instr):
- w = self.popvalue()
- if sys.version_info < (2, 7):
- v = self.popvalue()
- else:
- v = self.peekvalue(oparg - 1)
- self.space.call_method(v, 'append', w)
-
-
### ____________________________________________________________ ###
class ExitFrame(Exception):
diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -135,7 +135,7 @@
def type(self, obj):
class Type:
- def getname(self, space, default=u'?'):
+ def getname(self, space):
return unicode(type(obj).__name__)
return Type()
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -1075,10 +1075,6 @@
assert i > -1
assert isinstance(co.co_consts[i], frozenset)
-
-class AppTestCallMethod(object):
- spaceconfig = {'objspace.opcodes.CALL_METHOD': True}
-
def test_call_method_kwargs(self):
source = """def _f(a):
return a.f(a=a)
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -254,10 +254,6 @@
""")
-class TestExecutionContextWithCallMethod(TestExecutionContext):
- spaceconfig ={'objspace.opcodes.CALL_METHOD': True}
-
-
class AppTestDelNotBlocked:
def setup_method(self, meth):
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -844,9 +844,6 @@
assert len(called) == 1
assert isinstance(called[0], argument.Arguments)
-class TestPassThroughArguments_CALL_METHOD(TestPassThroughArguments):
- spaceconfig = {"objspace.opcodes.CALL_METHOD": True}
-
class AppTestKeywordsToBuiltinSanity(object):
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -54,6 +54,13 @@
if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
raise OperationError(space.w_SystemError,
space.wrap("libffi failed to build this callback"))
+ #
+ # We must setup the GIL here, in case the callback is invoked in
+ # some other non-Pythonic thread. This is the same as cffi on
+ # CPython.
+ if space.config.translation.thread:
+ from pypy.module.thread.os_thread import setup_threads
+ setup_threads(space)
def get_closure(self):
return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata)
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1516,13 +1516,18 @@
d = BStruct.fields
assert d[0][1].offset == d[1][1].offset == d[2][1].offset == 0
assert d[3][1].offset == sizeof(BLong)
- assert d[0][1].bitshift == 0
+ def f(m, r):
+ if sys.byteorder == 'little':
+ return r
+ else:
+ return LONGBITS - m - r
+ assert d[0][1].bitshift == f(1, 0)
assert d[0][1].bitsize == 1
- assert d[1][1].bitshift == 1
+ assert d[1][1].bitshift == f(2, 1)
assert d[1][1].bitsize == 2
- assert d[2][1].bitshift == 3
+ assert d[2][1].bitshift == f(3, 3)
assert d[2][1].bitsize == 3
- assert d[3][1].bitshift == 0
+ assert d[3][1].bitshift == f(LONGBITS - 5, 0)
assert d[3][1].bitsize == LONGBITS - 5
assert sizeof(BStruct) == 2 * sizeof(BLong)
assert alignof(BStruct) == alignof(BLong)
@@ -2856,7 +2861,7 @@
('b1', BInt, 9),
('b2', BUInt, 7),
('c', BChar, -1)], -1, -1, -1, flag)
- if flag % 2 == 0: # gcc and gcc ARM
+ if flag % 2 == 0: # gcc, any variant
assert typeoffsetof(BStruct, 'c') == (BChar, 3)
assert sizeof(BStruct) == 4
else: # msvc
@@ -2864,6 +2869,31 @@
assert sizeof(BStruct) == 12
assert alignof(BStruct) == 4
#
+ p = newp(new_pointer_type(BStruct), None)
+ p.a = b'A'
+ p.b1 = -201
+ p.b2 = 99
+ p.c = b'\x9D'
+ raw = buffer(p)[:]
+ if sys.byteorder == 'little':
+ if flag == 0 or flag == 2: # gcc, little endian
+ assert raw == b'A7\xC7\x9D'
+ elif flag == 1: # msvc
+ assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00'
+ elif flag == 4: # gcc, big endian
+ assert raw == b'A\xE3\x9B\x9D'
+ else:
+ raise AssertionError("bad flag")
+ else:
+ if flag == 0 or flag == 2: # gcc
+ assert raw == b'A\xC77\x9D'
+ elif flag == 1: # msvc
+ assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00'
+ elif flag == 4: # gcc, big endian
+ assert raw == b'A\x9B\xE3\x9D'
+ else:
+ raise AssertionError("bad flag")
+ #
BStruct = new_struct_type("struct foo2")
complete_struct_or_union(BStruct, [('a', BChar, -1),
('', BShort, 9),
@@ -2875,16 +2905,21 @@
elif flag == 1: # msvc
assert sizeof(BStruct) == 6
assert alignof(BStruct) == 2
- else: # gcc ARM
+ elif flag == 2: # gcc ARM
assert sizeof(BStruct) == 6
assert alignof(BStruct) == 2
+ elif flag == 4: # gcc, big endian
+ assert sizeof(BStruct) == 5
+ assert alignof(BStruct) == 1
+ else:
+ raise AssertionError("bad flag")
#
BStruct = new_struct_type("struct foo2")
complete_struct_or_union(BStruct, [('a', BChar, -1),
('', BInt, 0),
('', BInt, 0),
('c', BChar, -1)], -1, -1, -1, flag)
- if flag == 0: # gcc
+ if flag == 0: # gcc
assert typeoffsetof(BStruct, 'c') == (BChar, 4)
assert sizeof(BStruct) == 5
assert alignof(BStruct) == 1
@@ -2892,10 +2927,16 @@
assert typeoffsetof(BStruct, 'c') == (BChar, 1)
assert sizeof(BStruct) == 2
assert alignof(BStruct) == 1
- else: # gcc ARM
+ elif flag == 2: # gcc ARM
assert typeoffsetof(BStruct, 'c') == (BChar, 4)
assert sizeof(BStruct) == 8
assert alignof(BStruct) == 4
+ elif flag == 4: # gcc, big endian
+ assert typeoffsetof(BStruct, 'c') == (BChar, 4)
+ assert sizeof(BStruct) == 5
+ assert alignof(BStruct) == 1
+ else:
+ raise AssertionError("bad flag")
def test_bitfield_as_gcc():
@@ -2907,6 +2948,11 @@
def test_bitfield_as_arm_gcc():
_test_bitfield_details(flag=2)
+def test_bitfield_as_big_endian():
+ if '__pypy__' in sys.builtin_module_names:
+ py.test.skip("no big endian machine supported on pypy for now")
+ _test_bitfield_details(flag=4)
+
def test_version():
# this test is here mostly for PyPy
diff --git a/pypy/module/_continuation/interp_pickle.py b/pypy/module/_continuation/interp_pickle.py
--- a/pypy/module/_continuation/interp_pickle.py
+++ b/pypy/module/_continuation/interp_pickle.py
@@ -120,8 +120,7 @@
nkwds = (oparg >> 8) & 0xff
if nkwds == 0: # only positional arguments
# fast paths leaves things on the stack, pop them
- if (frame.space.config.objspace.opcodes.CALL_METHOD and
- opcode == map['CALL_METHOD']):
+ if opcode == map['CALL_METHOD']:
frame.dropvalues(nargs + 2)
elif opcode == map['CALL_FUNCTION']:
frame.dropvalues(nargs + 1)
diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py
--- a/pypy/module/_continuation/test/test_zpickle.py
+++ b/pypy/module/_continuation/test/test_zpickle.py
@@ -3,8 +3,7 @@
class AppTestCopy:
spaceconfig = dict(usemodules=['_continuation'],
- continuation=True,
- CALL_METHOD=True)
+ continuation=True)
def test_basic_setup(self):
from _continuation import continulet
@@ -106,7 +105,6 @@
spaceconfig = {
"usemodules": ['_continuation', 'struct', 'binascii'],
"continuation": True,
- "CALL_METHOD": True,
}
def setup_class(cls):
diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py
--- a/pypy/module/_lsprof/test/test_cprofile.py
+++ b/pypy/module/_lsprof/test/test_cprofile.py
@@ -191,11 +191,6 @@
sys.path.pop(0)
-class AppTestWithDifferentBytecodes(AppTestCProfile):
- spaceconfig = AppTestCProfile.spaceconfig.copy()
- spaceconfig['objspace.opcodes.CALL_METHOD'] = True
-
-
expected_output = {}
expected_output['print_stats'] = """\
119 function calls (99 primitive calls) in 1.000 seconds
diff --git a/pypy/module/_minimal_curses/fficurses.py b/pypy/module/_minimal_curses/fficurses.py
--- a/pypy/module/_minimal_curses/fficurses.py
+++ b/pypy/module/_minimal_curses/fficurses.py
@@ -26,6 +26,9 @@
def try_ldflags():
yield ExternalCompilationInfo(libraries=['curses'])
yield ExternalCompilationInfo(libraries=['curses', 'tinfo'])
+ yield ExternalCompilationInfo(libraries=['ncurses'])
+ yield ExternalCompilationInfo(libraries=['ncurses'],
+ library_dirs=['/usr/lib64'])
def try_tools():
try:
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -175,8 +175,8 @@
state = u'; dead'
else:
typename = space.type(w_obj).getname(space)
- objname = w_obj.getname(space, u'')
- if objname:
+ objname = w_obj.getname(space)
+ if objname and objname != u'?':
state = u"; to '%s' (%s)" % (typename, objname)
else:
state = u"; to '%s'" % (typename,)
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -245,7 +245,6 @@
it is necessary to serialize calls to this function."""
if not space.config.translation.thread:
raise NoThreads
- rthread.gc_thread_prepare()
# PyThreadState_Get will allocate a new execution context,
# we need to protect gc and other globals with the GIL.
rffi.aroundstate.after()
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -854,8 +854,7 @@
#
# default_magic - 6 -- used by CPython without the -U option
# default_magic - 5 -- used by CPython with the -U option
-# default_magic -- used by PyPy without the CALL_METHOD opcode
-# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode
+# default_magic -- used by PyPy [because of CALL_METHOD]
#
from pypy.interpreter.pycode import default_magic
MARSHAL_VERSION_FOR_PYC = 2
@@ -868,10 +867,7 @@
magic = __import__('imp').get_magic()
return struct.unpack('<i', magic)[0]
- result = default_magic
- if space.config.objspace.opcodes.CALL_METHOD:
- result += 2
- return result
+ return default_magic
def parse_source_module(space, pathname, source):
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -1137,6 +1137,7 @@
assert ret == 42
def test_pyc_magic_changes(self):
+ py.test.skip("For now, PyPy generates only one kind of .pyc files")
# test that the pyc files produced by a space are not reimportable
# from another, if they differ in what opcodes they support
allspaces = [self.space]
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -396,6 +396,8 @@
class W_UnicodeBox(W_CharacterBox):
def descr__new__unicode_box(space, w_subtype, w_arg):
+ raise OperationError(space.w_NotImplementedError, space.wrap("Unicode is not supported yet"))
+
from pypy.module.micronumpy.interp_dtype import new_unicode_dtype
arg = space.unicode_w(unicode_from_object(space, w_arg))
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -88,13 +88,27 @@
w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self)
return loop.getitem_filter(w_res, self, arr)
- def setitem_filter(self, space, idx, val):
+ def setitem_filter(self, space, idx, value):
+ from pypy.module.micronumpy.interp_boxes import Box
+ val = value
if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape():
raise OperationError(space.w_ValueError,
space.wrap("boolean index array should have 1 dimension"))
if idx.get_size() > self.get_size():
raise OperationError(space.w_ValueError,
space.wrap("index out of range for array"))
+ idx_iter = idx.create_iter(self.get_shape())
+ size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype())
+ if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]:
+ raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment "
+ "cannot assign %d input values to "
+ "the %d output values where the mask is true" % (val.get_shape()[0],size)))
+ if val.get_shape() == [1]:
+ box = val.descr_getitem(space, space.wrap(0))
+ assert isinstance(box, Box)
+ val = W_NDimArray(scalar.Scalar(val.get_dtype(), box))
+ elif val.get_shape() == [0]:
+ val.implementation.dtype = self.implementation.dtype
loop.setitem_filter(self, idx, val)
def _prepare_array_index(self, space, w_index):
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -132,7 +132,7 @@
reduce_driver = jit.JitDriver(name='numpy_reduce',
greens = ['shapelen', 'func', 'done_func',
- 'calc_dtype', 'identity'],
+ 'calc_dtype'],
reds = 'auto')
def compute_reduce(obj, calc_dtype, func, done_func, identity):
@@ -146,7 +146,7 @@
while not obj_iter.done():
reduce_driver.jit_merge_point(shapelen=shapelen, func=func,
done_func=done_func,
- calc_dtype=calc_dtype, identity=identity,
+ calc_dtype=calc_dtype,
)
rval = obj_iter.getitem().convert_to(calc_dtype)
if done_func is not None and done_func(calc_dtype, rval):
@@ -318,23 +318,27 @@
lefti.next()
return result
-count_all_true_driver = jit.JitDriver(name = 'numpy_count',
- greens = ['shapelen', 'dtype'],
- reds = 'auto')
def count_all_true(arr):
- s = 0
if arr.is_scalar():
return arr.get_dtype().itemtype.bool(arr.get_scalar_value())
iter = arr.create_iter()
- shapelen = len(arr.get_shape())
- dtype = arr.get_dtype()
+ return count_all_true_iter(iter, arr.get_shape(), arr.get_dtype())
+
+count_all_true_iter_driver = jit.JitDriver(name = 'numpy_count',
+ greens = ['shapelen', 'dtype'],
+ reds = 'auto')
+def count_all_true_iter(iter, shape, dtype):
+ s = 0
+ shapelen = len(shape)
+ dtype = dtype
while not iter.done():
- count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
+ count_all_true_iter_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
s += iter.getitem_bool()
iter.next()
return s
+
getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool',
greens = ['shapelen', 'arr_dtype',
'index_dtype'],
@@ -370,7 +374,7 @@
def setitem_filter(arr, index, value):
arr_iter = arr.create_iter()
- index_iter = index.create_iter()
+ index_iter = index.create_iter(arr.get_shape())
value_iter = value.create_iter()
shapelen = len(arr.get_shape())
index_dtype = index.get_dtype()
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1928,6 +1928,23 @@
a.fill(12)
assert (a == '1').all()
+ def test_boolean_indexing(self):
+ import numpypy as np
+ a = np.zeros((1, 3))
+ b = np.array([True])
+
+ assert (a[b] == a).all()
+
+ a[b] = 1.
+
+ assert (a == [[1., 1., 1.]]).all()
+
+ @py.test.mark.xfail
+ def test_boolean_array(self):
+ import numpypy as np
+ a = np.ndarray([1], dtype=bool)
+ assert a[0] == True
+
class AppTestMultiDim(BaseNumpyAppTest):
def test_init(self):
import numpypy
@@ -2335,6 +2352,21 @@
a[a & 1 == 0] = 15
assert (a == [[15, 1], [15, 5], [15, 9]]).all()
+ def test_array_indexing_bool_specialcases(self):
+ from numpypy import arange, array
+ a = arange(6)
+ try:
+ a[a < 3] = [1, 2]
+ assert False, "Should not work"
+ except ValueError:
+ pass
+ a = arange(6)
+ a[a > 3] = array([15])
+ assert (a == [0, 1, 2, 3, 15, 15]).all()
+ a = arange(6).reshape(3, 2)
+ a[a & 1 == 1] = [] # here, Numpy sticks garbage into the array
+ assert a.shape == (3, 2)
+
def test_copy_kwarg(self):
from numpypy import array
x = array([1, 2, 3])
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -56,7 +56,7 @@
elif isinstance(w_res, interp_boxes.W_BoolBox):
return float(w_res.value)
raise TypeError(w_res)
-
+
if self.graph is None:
interp, graph = self.meta_interp(f, [0],
listops=True,
@@ -139,11 +139,17 @@
'int_add': 3,
})
+ def define_reduce():
+ return """
+ a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ sum(a)
+ """
+
def test_reduce_compile_only_once(self):
self.compile_graph()
reset_stats()
pyjitpl._warmrunnerdesc.memory_manager.alive_loops.clear()
- i = self.code_mapping['sum']
+ i = self.code_mapping['reduce']
# run it twice
retval = self.interp.eval_graph(self.graph, [i])
retval = self.interp.eval_graph(self.graph, [i])
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -109,7 +109,8 @@
'posix', '_socket', '_sre', '_lsprof', '_weakref',
'__pypy__', 'cStringIO', '_collections', 'struct',
'mmap', 'marshal', '_codecs', 'rctime', 'cppyy',
- '_cffi_backend', 'pyexpat', '_continuation', '_io']:
+ '_cffi_backend', 'pyexpat', '_continuation', '_io',
+ 'thread']:
if modname == 'pypyjit' and 'interp_resop' in rest:
return False
return True
diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py
--- a/pypy/module/pypyjit/test/test_policy.py
+++ b/pypy/module/pypyjit/test/test_policy.py
@@ -45,6 +45,10 @@
from pypy.module._io.interp_bytesio import W_BytesIO
assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func)
+def test_thread():
+ from pypy.module.thread.os_lock import Lock
+ assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func)
+
def test_pypy_module():
from pypy.module._collections.interp_deque import W_Deque
from pypy.module._random.interp_random import W_Random
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -1,5 +1,3 @@
-
-import py, sys
from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
@@ -51,27 +49,6 @@
...
""")
- def test_list(self):
- def main(n):
- i = 0
- while i < n:
- z = list(())
- z.append(1)
- i += z[-1] / len(z)
- return i
-
- log = self.run(main, [1000])
- assert log.result == main(1000)
- loop, = log.loops_by_filename(self.filepath)
- assert loop.match("""
- i7 = int_lt(i5, i6)
- guard_true(i7, descr=...)
- guard_not_invalidated(descr=...)
- i9 = int_add(i5, 1)
- --TICK--
- jump(..., descr=...)
- """)
-
def test_non_virtual_dict(self):
def main(n):
i = 0
@@ -119,6 +96,30 @@
jump(..., descr=...)
""")
+
+
+class TestOtherContainers(BaseTestPyPyC):
+ def test_list(self):
+ def main(n):
+ i = 0
+ while i < n:
+ z = list(())
+ z.append(1)
+ i += z[-1] / len(z)
+ return i
+
+ log = self.run(main, [1000])
+ assert log.result == main(1000)
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i7 = int_lt(i5, i6)
+ guard_true(i7, descr=...)
+ guard_not_invalidated(descr=...)
+ i9 = int_add(i5, 1)
+ --TICK--
+ jump(..., descr=...)
+ """)
+
def test_floatlist_unpack_without_calls(self):
def fn(n):
l = [2.3, 3.4, 4.5]
@@ -130,8 +131,7 @@
ops = loop.ops_by_id('look')
assert 'call' not in log.opnames(ops)
- #XXX the following tests only work with strategies enabled
-
+ # XXX the following tests only work with strategies enabled
def test_should_not_create_intobject_with_sets(self):
def main(n):
i = 0
diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py
--- a/pypy/module/pypyjit/test_pypy_c/test_thread.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py
@@ -48,3 +48,47 @@
i58 = arraylen_gc(p43, descr=...)
jump(..., descr=...)
""")
+
+ def test_lock_acquire_release(self):
+ def main(n):
+ import threading
+ lock = threading.Lock()
+ while n > 0:
+ with lock:
+ n -= 1
+ log = self.run(main, [500])
+ assert log.result == main(500)
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i58 = int_gt(i43, 0)
+ guard_true(i58, descr=<Guard0x10483adb8>)
+ p59 = getfield_gc(p15, descr=<FieldP pypy.module.thread.os_lock.Lock.inst_lock 8>)
+ i60 = getfield_gc(p59, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+ p61 = force_token()
+ setfield_gc(p0, p61, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+ i62 = call_release_gil(4312440032, i60, 1, descr=<Calli 4 ii EF=6>)
+ guard_not_forced(descr=<Guard0x103f3cca0>)
+ guard_no_exception(descr=<Guard0x10483ad40>)
+ i63 = int_is_true(i62)
+ guard_true(i63, descr=<Guard0x10483acc8>)
+ i64 = int_sub(i43, 1)
+ guard_not_invalidated(descr=<Guard0x10483ac50>)
+ p66 = getfield_gc(p15, descr=<FieldP pypy.module.thread.os_lock.Lock.inst_lock 8>)
+ i67 = getfield_gc(p66, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+ p68 = force_token()
+ setfield_gc(p0, p68, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+ i69 = call_release_gil(4312440032, i67, 0, descr=<Calli 4 ii EF=6>)
+ guard_not_forced(descr=<Guard0x103f3cc20>)
+ guard_no_exception(descr=<Guard0x10483aae8>)
+ i70 = int_is_true(i69)
+ guard_false(i70, descr=<Guard0x10483aa70>)
+ i71 = getfield_gc(p66, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+ p72 = force_token()
+ setfield_gc(p0, p72, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+ call_release_gil(4312441056, i71, descr=<Callv 0 i EF=6>)
+ guard_not_forced(descr=<Guard0x103f3cba0>)
+ guard_no_exception(descr=<Guard0x10483a9f8>)
+ guard_not_invalidated(descr=<Guard0x10483a980>)
+ --TICK--
+ jump(..., descr=TargetToken(4361239720))
+ """)
diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py
--- a/pypy/module/sys/test/test_sysmodule.py
+++ b/pypy/module/sys/test/test_sysmodule.py
@@ -704,7 +704,3 @@
except:
assert g() is e
test_call_in_subfunction.expected = 'n'
-
-
-class AppTestSysExcInfoDirectCallMethod(AppTestSysExcInfoDirect):
- spaceconfig = {"objspace.opcodes.CALL_METHOD": True}
diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
@@ -199,6 +199,9 @@
typerepr = self.TypeRepr
ffi = FFI(backend=self.Backend())
ffi.cdef("struct foo { short a, b, c; };")
+ p = ffi.cast("short unsigned int", 0)
+ assert repr(p) == "<cdata 'unsigned short' 0>"
+ assert repr(ffi.typeof(p)) == typerepr % "unsigned short"
p = ffi.cast("unsigned short int", 0)
assert repr(p) == "<cdata 'unsigned short' 0>"
assert repr(ffi.typeof(p)) == typerepr % "unsigned short"
@@ -535,13 +538,13 @@
for c_type, expected_size in [
('char', 1),
('unsigned int', 4),
- ('char *', SIZE_OF_LONG),
+ ('char *', SIZE_OF_PTR),
('int[5]', 20),
('struct foo', 12),
('union foo', 4),
]:
size = ffi.sizeof(c_type)
- assert size == expected_size
+ assert size == expected_size, (size, expected_size, ctype)
def test_sizeof_cdata(self):
ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py
--- a/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/callback_in_thread.py
@@ -27,6 +27,7 @@
seen = []
@ffi.callback('int(*)(int,int)')
def mycallback(x, y):
+ time.sleep(0.022)
seen.append((x, y))
return 0
lib.threaded_ballback_test(mycallback)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_function.py b/pypy/module/test_lib_pypy/cffi_tests/test_function.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_function.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_function.py
@@ -382,3 +382,26 @@
sin100 = my_decorator(m.sin)
x = sin100(1.23)
assert x == math.sin(1.23) + 100
+
+ def test_free_callback_cycle(self):
+ if self.Backend is CTypesBackend:
+ py.test.skip("seems to fail with the ctypes backend on windows")
+ import weakref
+ def make_callback(data):
+ container = [data]
+ callback = ffi.callback('int()', lambda: len(container))
+ container.append(callback)
+ # Ref cycle: callback -> lambda (closure) -> container -> callback
+ return callback
+
+ class Data(object):
+ pass
+ ffi = FFI(backend=self.Backend())
+ data = Data()
+ callback = make_callback(data)
+ wr = weakref.ref(data)
+ del callback, data
+ for i in range(3):
+ if wr() is not None:
+ import gc; gc.collect()
+ assert wr() is None # 'data' does not leak
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_version.py b/pypy/module/test_lib_pypy/cffi_tests/test_version.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_version.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_version.py
@@ -8,6 +8,8 @@
BACKEND_VERSIONS = {
'0.4.2': '0.4', # did not change
+ '0.7.1': '0.7', # did not change
+ '0.7.2': '0.7', # did not change
}
def test_version():
@@ -22,7 +24,7 @@
content = open(p).read()
#
v = cffi.__version__
- assert ("version = '%s'\n" % v) in content
+ assert ("version = '%s'\n" % BACKEND_VERSIONS.get(v, v)) in content
assert ("release = '%s'\n" % v) in content
def test_doc_version_file():
@@ -45,4 +47,5 @@
v = cffi.__version__
p = os.path.join(parent, 'c', 'test_c.py')
content = open(p).read()
- assert ('assert __version__ == "%s"' % v) in content
+ assert (('assert __version__ == "%s"' % BACKEND_VERSIONS.get(v, v))
+ in content)
diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py
--- a/pypy/module/test_lib_pypy/test_curses.py
+++ b/pypy/module/test_lib_pypy/test_curses.py
@@ -1,4 +1,8 @@
import pytest
+import sys
+if sys.platform == 'win32':
+ #This module does not exist in windows
+ pytest.skip('no curses on windows')
# Check that lib_pypy.cffi finds the correct version of _cffi_backend.
# Otherwise, the test is skipped. It should never be skipped when run
More information about the pypy-commit
mailing list