Author: Hakan Ardo <[email protected]>
Branch: jit-short_from_state
Changeset: r44467:2bd1326af39e
Date: 2011-05-25 14:23 +0200
http://bitbucket.org/pypy/pypy/changeset/2bd1326af39e/
Log: hg merge default
diff --git a/pypy/jit/backend/test/calling_convention_test.py
b/pypy/jit/backend/test/calling_convention_test.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/test/calling_convention_test.py
@@ -0,0 +1,190 @@
+from pypy.jit.metainterp.history import (AbstractFailDescr,
+ AbstractDescr,
+ BasicFailDescr,
+ BoxInt, Box, BoxPtr,
+ LoopToken,
+ ConstInt, ConstPtr,
+ BoxObj, Const,
+ ConstObj, BoxFloat, ConstFloat)
+from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.typesystem import deref
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass
+from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.llinterp import LLException
+from pypy.jit.codewriter import heaptracker, longlong
+from pypy.rlib.rarithmetic import intmask
+from pypy.jit.backend.detect_cpu import getcpuclass
+from pypy.jit.backend.test.runner_test import Runner
+
+def boxfloat(x):
+ return BoxFloat(longlong.getfloatstorage(x))
+
+def constfloat(x):
+ return ConstFloat(longlong.getfloatstorage(x))
+class FakeStats(object):
+ pass
+class TestCallingConv(Runner):
+ type_system = 'lltype'
+ Ptr = lltype.Ptr
+ FuncType = lltype.FuncType
+
+ def __init__(self):
+ self.cpu = getcpuclass()(rtyper=None, stats=FakeStats())
+ self.cpu.setup_once()
+
+ @classmethod
+ def get_funcbox(cls, cpu, func_ptr):
+ addr = llmemory.cast_ptr_to_adr(func_ptr)
+ return ConstInt(heaptracker.adr2int(addr))
+
+ def test_call_aligned_with_args_on_the_stack(self):
+ from pypy.rlib.libffi import types
+ cpu = self.cpu
+ if not cpu.supports_floats:
+ py.test.skip('requires floats')
+
+
+ def func(*args):
+ return float(sum(args))
+
+ F = lltype.Float
+ I = lltype.Signed
+ floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56]
+ ints = [7, 11, 23, 13, -42, 1111, 95, 1]
+ for case in range(256):
+ result = 0.0
+ args = []
+ argslist = []
+ local_floats = list(floats)
+ local_ints = list(ints)
+ for i in range(8):
+ if case & (1<<i):
+ args.append(F)
+ arg = local_floats.pop()
+ result += arg
+ argslist.append(boxfloat(arg))
+ else:
+ args.append(I)
+ arg = local_ints.pop()
+ result += arg
+ argslist.append(BoxInt(arg))
+ FUNC = self.FuncType(args, F)
+ FPTR = self.Ptr(FUNC)
+ func_ptr = llhelper(FPTR, func)
+ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ funcbox = self.get_funcbox(cpu, func_ptr)
+
+ res = self.execute_operation(rop.CALL,
+ [funcbox] + argslist,
+ 'float', descr=calldescr)
+ assert abs(res.getfloat() - result) < 0.0001
+
+ def test_call_alignment_call_assembler(self):
+ from pypy.rlib.libffi import types
+ cpu = self.cpu
+ if not cpu.supports_floats:
+ py.test.skip('requires floats')
+
+ fdescr3 = BasicFailDescr(3)
+ fdescr4 = BasicFailDescr(4)
+
+ def assembler_helper(failindex, virtualizable):
+ assert 0, 'should not be called, but was with failindex (%d)' %
failindex
+ return 13
+
+ FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF],
+ lltype.Signed))
+ class FakeJitDriverSD:
+ index_of_virtualizable = -1
+ _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
+ assembler_helper_adr = llmemory.cast_ptr_to_adr(
+ _assembler_helper_ptr)
+
+ floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56]
+ ints = [7, 11, 23, 42, -42, 1111, 95, 1]
+ def _prepare_args(args):
+ local_floats = list(floats)
+ local_ints = list(ints)
+ expected_result = 0.0
+ for i in range(len(args)):
+ x = args[i]
+ if x[0] == 'f':
+ x = local_floats.pop()
+ t = longlong.getfloatstorage(x)
+ cpu.set_future_value_float(i, t)
+ else:
+ x = local_ints.pop()
+ cpu.set_future_value_int(i, x)
+ expected_result += x
+ return expected_result
+
+ for case in range(256):
+ float_count = 0
+ int_count = 0
+ args = []
+ called_ops = ''
+ total_index = -1
+ for i in range(8):
+ if case & (1<<i):
+ args.append('f%d' % float_count)
+ else:
+ args.append('i%d' % int_count)
+ called_ops += 'f%d = cast_int_to_float(i%d)\n' % (
+ float_count, int_count)
+ int_count += 1
+ if total_index == -1:
+ total_index = float_count
+ float_count += 1
+ else:
+ called_ops += 'f%d = float_add(f%d, f%d)\n' % (
+ float_count + 1, total_index, float_count)
+ total_index = float_count + 1
+ float_count += 2
+ arguments = ', '.join(args)
+ called_ops = '[%s]\n' % arguments + called_ops
+ called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index
+ # compile called loop
+ called_loop = parse(called_ops, namespace=locals())
+ called_looptoken = LoopToken()
+ called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
+ done_number =
self.cpu.get_fail_descr_number(called_loop.operations[-1].getdescr())
+ self.cpu.compile_loop(called_loop.inputargs,
called_loop.operations, called_looptoken)
+
+ expected_result = _prepare_args(args)
+ res = cpu.execute_token(called_looptoken)
+ assert res.identifier == 3
+ t = longlong.getrealfloat(cpu.get_latest_value_float(0))
+ assert abs(t - expected_result) < 0.0001
+
+ ARGS = []
+ RES = lltype.Float
+ for x in args:
+ if x[0] == 'f':
+ ARGS.append(lltype.Float)
+ else:
+ ARGS.append(lltype.Signed)
+ FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
+ lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
+ ops = '''
+ [%s]
+ f99 = call_assembler(%s, descr=called_looptoken)
+ guard_not_forced()[]
+ finish(f99, descr=fdescr4)
+ ''' % (arguments, arguments)
+ loop = parse(ops, namespace=locals())
+ # we want to take the fast path
+ self.cpu.done_with_this_frame_float_v = done_number
+ try:
+ othertoken = LoopToken()
+ self.cpu.compile_loop(loop.inputargs, loop.operations,
othertoken)
+
+ # prepare call to called_loop
+ _prepare_args(args)
+ res = cpu.execute_token(othertoken)
+ x = longlong.getrealfloat(cpu.get_latest_value_float(0))
+ assert res.identifier == 4
+ assert abs(x - expected_result) < 0.0001
+ finally:
+ del self.cpu.done_with_this_frame_float_v
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -137,10 +137,11 @@
self.current_clt = looptoken.compiled_loop_token
self.pending_guard_tokens = []
self.mc = codebuf.MachineCodeBlockWrapper()
- if self.datablockwrapper is None:
- allblocks = self.get_asmmemmgr_blocks(looptoken)
- self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
- allblocks)
+ #assert self.datablockwrapper is None --- but obscure case
+ # possible, e.g. getting MemoryError and continuing
+ allblocks = self.get_asmmemmgr_blocks(looptoken)
+ self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
+ allblocks)
def teardown(self):
self.pending_guard_tokens = None
@@ -678,27 +679,29 @@
nonfloatlocs, floatlocs = arglocs
self._call_header_with_stack_check()
self.mc.LEA_rb(esp.value, self._get_offset_of_ebp_from_esp(stackdepth))
- for i in range(len(nonfloatlocs)):
- loc = nonfloatlocs[i]
- if isinstance(loc, RegLoc):
- assert not loc.is_xmm
- self.mc.MOV_rb(loc.value, (2 + i) * WORD)
- loc = floatlocs[i]
- if isinstance(loc, RegLoc):
- assert loc.is_xmm
- self.mc.MOVSD_xb(loc.value, (1 + i) * 2 * WORD)
+ offset = 2 * WORD
tmp = eax
xmmtmp = xmm0
for i in range(len(nonfloatlocs)):
loc = nonfloatlocs[i]
- if loc is not None and not isinstance(loc, RegLoc):
- self.mc.MOV_rb(tmp.value, (2 + i) * WORD)
- self.mc.MOV(loc, tmp)
+ if loc is not None:
+ if isinstance(loc, RegLoc):
+ assert not loc.is_xmm
+ self.mc.MOV_rb(loc.value, offset)
+ else:
+ self.mc.MOV_rb(tmp.value, offset)
+ self.mc.MOV(loc, tmp)
+ offset += WORD
loc = floatlocs[i]
- if loc is not None and not isinstance(loc, RegLoc):
- self.mc.MOVSD_xb(xmmtmp.value, (1 + i) * 2 * WORD)
- assert isinstance(loc, StackLoc)
- self.mc.MOVSD_bx(loc.value, xmmtmp.value)
+ if loc is not None:
+ if isinstance(loc, RegLoc):
+ assert loc.is_xmm
+ self.mc.MOVSD_xb(loc.value, offset)
+ else:
+ self.mc.MOVSD_xb(xmmtmp.value, offset)
+ assert isinstance(loc, StackLoc)
+ self.mc.MOVSD_bx(loc.value, xmmtmp.value)
+ offset += 2 * WORD
endpos = self.mc.get_relative_pos() + 5
self.mc.JMP_l(jmppos - endpos)
assert endpos == self.mc.get_relative_pos()
diff --git a/pypy/jit/backend/x86/test/test_calling_convention.py
b/pypy/jit/backend/x86/test/test_calling_convention.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/x86/test/test_calling_convention.py
@@ -0,0 +1,1 @@
+from pypy.jit.backend.test.calling_convention_test import TestCallingConv
diff --git a/pypy/module/__builtin__/app_inspect.py
b/pypy/module/__builtin__/app_inspect.py
--- a/pypy/module/__builtin__/app_inspect.py
+++ b/pypy/module/__builtin__/app_inspect.py
@@ -5,6 +5,8 @@
import sys
+from __pypy__ import lookup_special
+
def _caller_locals():
# note: the reason why this is working is because the functions in here are
# compiled by geninterp, so they don't have a frame
@@ -62,7 +64,22 @@
obj = args[0]
- if isinstance(obj, types.ModuleType):
+ dir_meth = None
+ if isinstance(obj, types.InstanceType):
+ try:
+ dir_meth = getattr(obj, "__dir__")
+ except AttributeError:
+ pass
+ else:
+ dir_meth = lookup_special(obj, "__dir__")
+ if dir_meth is not None:
+ result = dir_meth()
+ if not isinstance(result, list):
+ raise TypeError("__dir__() must return a list, not %r" % (
+ type(result),))
+ result.sort()
+ return result
+ elif isinstance(obj, types.ModuleType):
try:
result = list(obj.__dict__)
result.sort()
@@ -76,14 +93,6 @@
result.sort()
return result
- elif hasattr(type(obj), '__dir__'):
- result = type(obj).__dir__(obj)
- if not isinstance(result, list):
- raise TypeError("__dir__() must return a list, not %r" % (
- type(result),))
- result.sort()
- return result
-
else: #(regular item)
Dict = {}
try:
diff --git a/pypy/module/__builtin__/test/test_builtin.py
b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -120,15 +120,32 @@
def test_dir_custom(self):
class Foo(object):
def __dir__(self):
- return [1, 3, 2]
+ return ["1", "2", "3"]
f = Foo()
- assert dir(f) == [1, 2, 3]
- #
+ assert dir(f) == ["1", "2", "3"]
+ class Foo:
+ def __dir__(self):
+ return ["apple"]
+ assert dir(Foo()) == ["apple"]
class Foo(object):
def __dir__(self):
return 42
f = Foo()
raises(TypeError, dir, f)
+ import types
+ class Foo(types.ModuleType):
+ def __dir__(self):
+ return ["blah"]
+ assert dir(Foo("a_mod")) == ["blah"]
+
+ def test_dir_custom_lookup(self):
+ class M(type):
+ def __dir__(self, *args): return ["14"]
+ class X(object):
+ __metaclass__ = M
+ x = X()
+ x.__dir__ = lambda x: ["14"]
+ assert dir(x) != ["14"]
def test_format(self):
assert format(4) == "4"
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -16,6 +16,7 @@
'debug_stop' : 'interp_debug.debug_stop',
'debug_print_once' : 'interp_debug.debug_print_once',
'builtinify' : 'interp_magic.builtinify',
+ 'lookup_special' : 'interp_magic.lookup_special',
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_magic.py
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -1,9 +1,9 @@
+from pypy.interpreter.baseobjspace import ObjSpace, W_Root
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import unwrap_spec
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.typeobject import MethodCache
from pypy.objspace.std.mapdict import IndexCache
-from pypy.module._file.interp_file import W_File
def internal_repr(space, w_object):
@@ -59,3 +59,14 @@
func = space.interp_w(Function, w_func)
bltn = BuiltinFunction(func)
return space.wrap(bltn)
+
+@unwrap_spec(ObjSpace, W_Root, str)
+def lookup_special(space, w_obj, meth):
+ """Lookup up a special method on an object."""
+ if space.is_oldstyle_instance(w_obj):
+ w_msg = space.wrap("this doesn't do what you want on old-style
classes")
+ raise OperationError(space.w_TypeError, w_msg)
+ w_descr = space.lookup(w_obj, meth)
+ if w_descr is None:
+ return space.w_None
+ return space.get(w_descr, w_obj)
diff --git a/pypy/module/__pypy__/test/test_special.py
b/pypy/module/__pypy__/test/test_special.py
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -36,3 +36,16 @@
assert not hasattr(A.b, 'im_func')
assert A.a is not A.__dict__['a']
assert A.b is A.__dict__['b']
+
+ def test_lookup_special(self):
+ from __pypy__ import lookup_special
+ class X(object):
+ def foo(self): return 42
+ x = X()
+ x.foo = 23
+ x.bar = 80
+ assert lookup_special(x, "foo")() == 42
+ assert lookup_special(x, "bar") is None
+ class X:
+ pass
+ raises(TypeError, lookup_special, X(), "foo")
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
@@ -1,9 +1,10 @@
import py
+from pypy.interpreter.argument import Arguments
from pypy.interpreter.baseobjspace import Wrappable, W_Root
-from pypy.interpreter.argument import Arguments
from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import interp2app, ObjSpace
from pypy.interpreter.typedef import GetSetProperty, TypeDef
-from pypy.interpreter.gateway import interp2app, ObjSpace
+from pypy.rlib import jit
import weakref
@@ -13,7 +14,7 @@
self.refs_weak = []
self.cached_weakref_index = -1
self.cached_proxy_index = -1
-
+
def __del__(self):
"""This runs when the interp-level object goes away, and allows
its lifeline to go away. The purpose of this is to activate the
@@ -37,6 +38,7 @@
# weakref callbacks are not invoked eagerly here. They are
# invoked by self.__del__() anyway.
+ @jit.dont_look_inside
def get_or_make_weakref(self, space, w_subtype, w_obj, w_callable):
w_weakreftype = space.gettypeobject(W_Weakref.typedef)
is_weakreftype = space.is_w(w_weakreftype, w_subtype)
@@ -55,6 +57,7 @@
self.cached_weakref_index = index
return w_ref
+ @jit.dont_look_inside
def get_or_make_proxy(self, space, w_obj, w_callable):
can_reuse = space.is_w(w_callable, space.w_None)
if can_reuse and self.cached_proxy_index >= 0:
@@ -81,7 +84,7 @@
w_weakreftype = space.gettypeobject(W_Weakref.typedef)
for i in range(len(self.refs_weak)):
w_ref = self.refs_weak[i]()
- if (w_ref is not None and
+ if (w_ref is not None and
space.is_true(space.isinstance(w_ref, w_weakreftype))):
return w_ref
return space.w_None
@@ -106,6 +109,7 @@
w_self.w_obj_weak = weakref.ref(w_obj)
w_self.w_callable = w_callable
+ @jit.dont_look_inside
def dereference(self):
w_obj = self.w_obj_weak()
return w_obj
@@ -244,7 +248,7 @@
lifeline = w_obj.getweakref()
if lifeline is None:
lifeline = WeakrefLifeline(space)
- w_obj.setweakref(space, lifeline)
+ w_obj.setweakref(space, lifeline)
return lifeline.get_or_make_proxy(space, w_obj, w_callable)
def descr__new__proxy(space, w_subtype, w_obj, w_callable=None):
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
@@ -14,7 +14,7 @@
modname, _ = modname.split('.', 1)
if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions',
'imp', 'sys', 'array', '_ffi', 'itertools', 'operator',
- 'posix', '_socket', '_sre', '_lsprof']:
+ 'posix', '_socket', '_sre', '_lsprof', '_weakref']:
return True
return False
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -270,9 +270,8 @@
i17 = int_add_ovf(i8, 1)
guard_no_overflow(descr=<Guard5>)
i18 = force_token()
- i20 = int_sub(i17, 1)
--TICK--
- jump(p0, p1, p2, p3, p4, p5, i20, p7, i17, i9, p10, p11, p12,
descr=<Loop0>)
+ jump(p0, p1, p2, p3, p4, p5, i8, p7, i17, i9, p10, p11, p12,
descr=<Loop0>)
""")
def test_default_and_kw(self):
diff --git a/pypy/module/zipimport/test/test_zipimport.py
b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -1,7 +1,7 @@
from pypy.conftest import gettestobjspace
import marshal
-import py
+import py, os
import time
import struct
from pypy.module.imp.importing import get_pyc_magic, _w_long
@@ -15,6 +15,7 @@
cpy's regression tests
"""
compression = ZIP_STORED
+ pathsep = '/'
def make_pyc(cls, space, co, mtime):
data = marshal.dumps(co)
@@ -57,6 +58,7 @@
test_pyc = cls.make_pyc(space, co, now)
cls.w_test_pyc = space.wrap(test_pyc)
cls.w_compression = space.wrap(cls.compression)
+ cls.w_pathsep = space.wrap(cls.pathsep)
#ziptestmodule = tmpdir.ensure('ziptestmodule.zip').write(
ziptestmodule = tmpdir.join("somezip.zip")
cls.w_tmpzip = space.wrap(str(ziptestmodule))
@@ -100,6 +102,7 @@
from zipfile import ZipFile, ZipInfo
z = ZipFile(self.zipfile, 'w')
write_files = self.write_files
+ filename = filename.replace('/', self.pathsep)
write_files.append((filename, data))
for filename, data in write_files:
zinfo = ZipInfo(filename, time.localtime(self.now))
@@ -121,6 +124,7 @@
del _zip_directory_cache[self.zipfile]
def test_cache_subdir(self):
+ import os
self.writefile('x.py', '')
self.writefile('sub/__init__.py', '')
self.writefile('sub/yy.py', '')
@@ -130,7 +134,7 @@
assert main_importer is not sub_importer
assert main_importer.prefix == ""
- assert sub_importer.prefix == "sub/"
+ assert sub_importer.prefix == "sub" + os.path.sep
def test_good_bad_arguments(self):
from zipimport import zipimporter
@@ -262,7 +266,7 @@
import zipimport
data = "saddsadsa"
self.writefile("xxx", data)
- self.writefile("xx"+os.sep+"__init__.py", "5")
+ self.writefile("xx/__init__.py", "5")
self.writefile("yy.py", "3")
self.writefile('uu.pyc', self.test_pyc)
z = zipimport.zipimporter(self.zipfile)
@@ -287,8 +291,7 @@
"""
import os
import zipimport
- self.writefile(
- os.sep.join(("directory", "package", "__init__.py")), "")
+ self.writefile("directory/package/__init__.py", "")
importer = zipimport.zipimporter(self.zipfile + "/directory")
# Grab this so if the assertion fails, py.test will display its
# value. Not sure why it doesn't the assertion uses import.archive
@@ -296,15 +299,14 @@
archive = importer.archive
realprefix = importer.prefix
allbutlast = self.zipfile.split(os.path.sep)[:-1]
- prefix = 'directory/'
+ prefix = 'directory' + os.path.sep
assert archive == self.zipfile
assert realprefix == prefix
def test_subdirectory_importer(self):
import os
import zipimport
- self.writefile(
- os.sep.join(("directory", "package", "__init__.py")), "")
+ self.writefile("directory/package/__init__.py", "")
z = zipimport.zipimporter(self.zipfile + "/directory")
mod = z.load_module("package")
assert z.is_package("package")
@@ -313,14 +315,9 @@
def test_subdirectory_twice(self):
import os, zipimport
- self.writefile(
- os.sep.join(("package", "__init__.py")), "")
- self.writefile(
- os.sep.join(("package", "subpackage",
- "__init__.py")), "")
- self.writefile(
- os.sep.join(("package", "subpackage",
- "foo.py")), "")
+ self.writefile("package/__init__.py", "")
+ self.writefile("package/subpackage/__init__.py", "")
+ self.writefile("package/subpackage/foo.py", "")
import sys
print sys.path
mod = __import__('package.subpackage.foo', None, None, [])
@@ -331,8 +328,7 @@
"""
import os
import zipimport
- self.writefile(
- os.sep.join(("directory", "package", "__init__.py")), "")
+ self.writefile("directory/package/__init__.py", "")
importer = zipimport.zipimporter(self.zipfile + "/directory")
l = [i for i in zipimport._zip_directory_cache]
assert len(l)
@@ -370,3 +366,8 @@
except ImportError:
py.test.skip("zlib not available, cannot test compressed zipfiles")
cls.make_class()
+
+
+if os.sep != '/':
+ class AppTestNativePathSep(AppTestZipimport):
+ pathsep = os.sep
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -207,34 +207,51 @@
return space.get_and_call_function(w_descr, w_obj, w_name)
def is_true(space, w_obj):
- w_descr = space.lookup(w_obj, '__nonzero__')
+ method = "__nonzero__"
+ w_descr = space.lookup(w_obj, method)
if w_descr is None:
- w_descr = space.lookup(w_obj, '__len__')
+ method = "__len__"
+ w_descr = space.lookup(w_obj, method)
if w_descr is None:
return True
w_res = space.get_and_call_function(w_descr, w_obj)
# more shortcuts for common cases
- if w_res is space.w_False:
+ if space.is_w(w_res, space.w_False):
return False
- if w_res is space.w_True:
+ if space.is_w(w_res, space.w_True):
return True
w_restype = space.type(w_res)
- if (space.is_w(w_restype, space.w_bool) or
- space.is_w(w_restype, space.w_int)):
+ # Note there is no check for bool here because the only possible
+ # instances of bool are w_False and w_True, which are checked above.
+ if (space.is_w(w_restype, space.w_int) or
+ space.is_w(w_restype, space.w_long)):
return space.int_w(w_res) != 0
else:
- raise OperationError(space.w_TypeError,
- space.wrap('__nonzero__ should return '
- 'bool or int'))
+ msg = "%s should return bool or integer" % (method,)
+ raise OperationError(space.w_TypeError, space.wrap(msg))
- def nonzero(self, w_obj):
- if self.is_true(w_obj):
- return self.w_True
+ def nonzero(space, w_obj):
+ if space.is_true(w_obj):
+ return space.w_True
else:
- return self.w_False
+ return space.w_False
-## def len(self, w_obj):
-## XXX needs to check that the result is an int (or long?) >= 0
+ def len(space, w_obj):
+ w_descr = space.lookup(w_obj, '__len__')
+ if w_descr is None:
+ name = space.type(w_obj).getname(space)
+ msg = "'%s' has no length" % (name,)
+ raise OperationError(space.w_TypeError, space.wrap(msg))
+ w_res = space.get_and_call_function(w_descr, w_obj)
+ space._check_len_result(w_res)
+ return w_res
+
+ def _check_len_result(space, w_obj):
+ # Will complain if result is too big.
+ result = space.int_w(w_obj)
+ if result < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("__len__() should return >= 0"))
def iter(space, w_obj):
w_descr = space.lookup(w_obj, '__iter__')
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
@@ -266,6 +266,7 @@
return None
def unwrap(self, w_obj):
+ """NOT_RPYTHON"""
if isinstance(w_obj, Wrappable):
return w_obj
if isinstance(w_obj, model.W_Object):
diff --git a/pypy/objspace/test/test_descroperation.py
b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -524,6 +524,31 @@
assert issubclass(B, B)
assert issubclass(23, B)
+ def test_truth_of_long(self):
+ class X(object):
+ def __len__(self): return 1L
+ __nonzero__ = __len__
+ assert X()
+ del X.__nonzero__
+ assert X()
+
+ def test_len_overflow(self):
+ import sys
+ class X(object):
+ def __len__(self):
+ return sys.maxsize + 1
+ raises(OverflowError, len, X())
+
+ def test_len_underflow(self):
+ import sys
+ class X(object):
+ def __len__(self):
+ return -1
+ raises(ValueError, len, X())
+ class Y(object):
+ def __len__(self):
+ return -1L
+ raises(ValueError, len, Y())
class AppTestWithBuiltinShortcut(AppTest_Descroperation):
OPTIONS = {'objspace.std.builtinshortcut': True}
diff --git a/pypy/rlib/test/test_debug.py b/pypy/rlib/test/test_debug.py
--- a/pypy/rlib/test/test_debug.py
+++ b/pypy/rlib/test/test_debug.py
@@ -2,7 +2,7 @@
import py
from pypy.rlib.debug import check_annotation, make_sure_not_resized
from pypy.rlib.debug import debug_print, debug_start, debug_stop
-from pypy.rlib.debug import have_debug_prints, debug_offset
+from pypy.rlib.debug import have_debug_prints, debug_offset, debug_flush
from pypy.rlib.debug import check_nonneg, IntegerCanBeNegative
from pypy.rlib import debug
from pypy.rpython.test.test_llinterp import interpret
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit