Author: David Schneider <david.schnei...@picle.org> Branch: arm-backend-2 Changeset: r55614:36790dfd7dae Date: 2012-04-18 13:03 +0000 http://bitbucket.org/pypy/pypy/changeset/36790dfd7dae/
Log: merge default diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -320,10 +320,14 @@ default=False), BoolOption("getattributeshortcut", "track types that override __getattribute__", - default=False), + default=False, + # weakrefs needed, because of get_subclasses() + requires=[("translation.rweakref", True)]), BoolOption("newshortcut", "cache and shortcut calling __new__ from builtin types", - default=False), + default=False, + # weakrefs needed, because of get_subclasses() + requires=[("translation.rweakref", True)]), BoolOption("logspaceoptypes", "a instrumentation option: before exit, print the types seen by " @@ -337,7 +341,9 @@ requires=[("objspace.std.builtinshortcut", True)]), BoolOption("withidentitydict", "track types that override __hash__, __eq__ or __cmp__ and use a special dict strategy for those which do not", - default=False), + default=False, + # weakrefs needed, because of get_subclasses() + requires=[("translation.rweakref", True)]), ]), ]) diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -85,6 +85,10 @@ Collects the arguments of a function call. Instances should be considered immutable. + + Some parts of this class are written in a slightly convoluted style to help + the JIT. It is really crucial to get this right, because Python's argument + semantics are complex, but calls occur everywhere. """ ### Construction ### @@ -171,7 +175,13 @@ space = self.space keywords, values_w = space.view_as_kwargs(w_starstararg) if keywords is not None: # this path also taken for empty dicts - self._add_keywordargs_no_unwrapping(keywords, values_w) + if self.keywords is None: + self.keywords = keywords[:] # copy to make non-resizable + self.keywords_w = values_w[:] + else: + self._check_not_duplicate_kwargs(keywords, values_w) + self.keywords = self.keywords + keywords + self.keywords_w = self.keywords_w + values_w return not jit.isconstant(len(self.keywords)) if space.isinstance_w(w_starstararg, space.w_dict): keys_w = space.unpackiterable(w_starstararg) @@ -229,22 +239,16 @@ @jit.look_inside_iff(lambda self, keywords, keywords_w: jit.isconstant(len(keywords) and jit.isconstant(self.keywords))) - def _add_keywordargs_no_unwrapping(self, keywords, keywords_w): - if self.keywords is None: - self.keywords = keywords[:] # copy to make non-resizable - self.keywords_w = keywords_w[:] - else: - # looks quadratic, but the JIT should remove all of it nicely. - # Also, all the lists should be small - for key in keywords: - for otherkey in self.keywords: - if otherkey == key: - raise operationerrfmt(self.space.w_TypeError, - "got multiple values " - "for keyword argument " - "'%s'", key) - self.keywords = self.keywords + keywords - self.keywords_w = self.keywords_w + keywords_w + def _check_not_duplicate_kwargs(self, keywords, keywords_w): + # looks quadratic, but the JIT should remove all of it nicely. + # Also, all the lists should be small + for key in keywords: + for otherkey in self.keywords: + if otherkey == key: + raise operationerrfmt(self.space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) def fixedunpack(self, argcount): """The simplest argument parsing: get the 'argcount' arguments, diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -1223,7 +1223,7 @@ def run_one_step(self): # Execute the frame forward. This method contains a loop that leaves # whenever the 'opcode_implementations' (which is one of the 'opimpl_' - # methods) returns True. This is the case when the current frame + # methods) raises ChangeFrame. This is the case when the current frame # changes, due to a call or a return. try: staticdata = self.metainterp.staticdata diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py --- a/pypy/module/_io/interp_iobase.py +++ b/pypy/module/_io/interp_iobase.py @@ -341,9 +341,13 @@ def add(self, w_iobase): assert w_iobase.streamholder is None - holder = StreamHolder(w_iobase) - w_iobase.streamholder = holder - self.streams[holder] = None + if rweakref.has_weakref_support(): + holder = StreamHolder(w_iobase) + w_iobase.streamholder = holder + self.streams[holder] = None + #else: + # no support for weakrefs, so ignore and we + # will not get autoflushing def remove(self, w_iobase): holder = w_iobase.streamholder diff --git a/pypy/module/cpyext/iterator.py b/pypy/module/cpyext/iterator.py --- a/pypy/module/cpyext/iterator.py +++ b/pypy/module/cpyext/iterator.py @@ -22,7 +22,7 @@ cannot be iterated.""" return space.iter(w_obj) -@cpython_api([PyObject], PyObject, error=CANNOT_FAIL) +@cpython_api([PyObject], PyObject) def PyIter_Next(space, w_obj): """Return the next value from the iteration o. If the object is an iterator, this retrieves the next value from the iteration, and returns diff --git a/pypy/module/cpyext/test/test_iterator.py b/pypy/module/cpyext/test/test_iterator.py --- a/pypy/module/cpyext/test/test_iterator.py +++ b/pypy/module/cpyext/test/test_iterator.py @@ -15,3 +15,8 @@ assert space.unwrap(api.PyIter_Next(w_iter)) == 3 assert api.PyIter_Next(w_iter) is None assert not api.PyErr_Occurred() + + def test_iternext_error(self,space, api): + assert api.PyIter_Next(space.w_None) is None + assert api.PyErr_Occurred() is space.w_TypeError + api.PyErr_Clear() diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -453,8 +453,8 @@ def test_tailmatch(self, space, api): w_str = space.wrap(u"abcdef") - assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, 1) == 1 - assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, -1) == 1 + assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, -1) == 1 + assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, 1) == 1 self.raises(space, api, TypeError, api.PyUnicode_Tailmatch, w_str, space.wrap(3), 2, 10, 1) diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -593,7 +593,7 @@ suffix match), 0 otherwise. Return -1 if an error occurred.""" str = space.unicode_w(w_str) substr = space.unicode_w(w_substr) - if rffi.cast(lltype.Signed, direction) >= 0: + if rffi.cast(lltype.Signed, direction) <= 0: return stringtype.stringstartswith(str, substr, start, end) else: return stringtype.stringendswith(str, substr, start, end) diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -762,6 +762,8 @@ def test_logaddexp(self): import math + import sys + float_max, float_min = sys.float_info.max, sys.float_info.min from _numpypy import logaddexp # From the numpy documentation @@ -772,7 +774,8 @@ assert logaddexp(0, 0) == math.log(2) assert logaddexp(float('-inf'), 0) == 0 - assert logaddexp(12345678, 12345678) == float('inf') + assert logaddexp(float_max, float_max) == float_max + assert logaddexp(float_min, float_min) == math.log(2) assert math.isnan(logaddexp(float('nan'), 1)) assert math.isnan(logaddexp(1, float('nan'))) @@ -785,6 +788,8 @@ def test_logaddexp2(self): import math + import sys + float_max, float_min = sys.float_info.max, sys.float_info.min from _numpypy import logaddexp2 log2 = math.log(2) @@ -796,7 +801,8 @@ assert logaddexp2(0, 0) == 1 assert logaddexp2(float('-inf'), 0) == 0 - assert logaddexp2(12345678, 12345678) == float('inf') + assert logaddexp2(float_max, float_max) == float_max + assert logaddexp2(float_min, float_min) == 1.0 assert math.isnan(logaddexp2(float('nan'), 1)) assert math.isnan(logaddexp2(1, float('nan'))) diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -17,6 +17,7 @@ 'render_as_void': True}) degToRad = math.pi / 180.0 log2 = math.log(2) +log2e = 1./log2 def simple_unary_op(func): specialize.argtype(1)(func) @@ -841,45 +842,26 @@ @simple_binary_op def logaddexp(self, v1, v2): - try: - v1e = math.exp(v1) - except OverflowError: - v1e = rfloat.INFINITY - try: - v2e = math.exp(v2) - except OverflowError: - v2e = rfloat.INFINITY + tmp = v1 - v2 + if tmp > 0: + return v1 + rfloat.log1p(math.exp(-tmp)) + elif tmp <= 0: + return v2 + rfloat.log1p(math.exp(tmp)) + else: + return v1 + v2 - v12e = v1e + v2e - try: - return math.log(v12e) - except ValueError: - if v12e == 0.0: - # CPython raises ValueError here, so we have to check - # the value to find the correct numpy return value - return -rfloat.INFINITY - return rfloat.NAN + def npy_log2_1p(self, v): + return log2e * rfloat.log1p(v) @simple_binary_op def logaddexp2(self, v1, v2): - try: - v1e = math.pow(2, v1) - except OverflowError: - v1e = rfloat.INFINITY - try: - v2e = math.pow(2, v2) - except OverflowError: - v2e = rfloat.INFINITY - - v12e = v1e + v2e - try: - return math.log(v12e) / log2 - except ValueError: - if v12e == 0.0: - # CPython raises ValueError here, so we have to check - # the value to find the correct numpy return value - return -rfloat.INFINITY - return rfloat.NAN + tmp = v1 - v2 + if tmp > 0: + return v1 + self.npy_log2_1p(math.pow(2, -tmp)) + if tmp <= 0: + return v2 + self.npy_log2_1p(math.pow(2, tmp)) + else: + return v1 + v2 class NonNativeFloat(NonNativePrimitive, Float): _mixin_ = True diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -414,7 +414,8 @@ def contains(space, w_container, w_item): w_descr = space.lookup(w_container, '__contains__') if w_descr is not None: - return space.get_and_call_function(w_descr, w_container, w_item) + w_result = space.get_and_call_function(w_descr, w_container, w_item) + return space.nonzero(w_result) return space._contains(w_container, w_item) def _contains(space, w_container, w_item): 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 @@ -694,5 +694,31 @@ l = len(X(X(2))) assert l == 2 and type(l) is int + def test_bool___contains__(self): + class X(object): + def __contains__(self, item): + if item == 'foo': + return 42 + else: + return 'hello world' + x = X() + res = 'foo' in x + assert res is True + res = 'bar' in x + assert res is True + # + class MyError(Exception): + pass + class CannotConvertToBool(object): + def __nonzero__(self): + raise MyError + class X(object): + def __contains__(self, item): + return CannotConvertToBool() + x = X() + raises(MyError, "'foo' in x") + + + class AppTestWithBuiltinShortcut(AppTest_Descroperation): OPTIONS = {'objspace.std.builtinshortcut': True} diff --git a/pypy/rlib/parsing/test/test_ebnfparse.py b/pypy/rlib/parsing/test/test_ebnfparse.py --- a/pypy/rlib/parsing/test/test_ebnfparse.py +++ b/pypy/rlib/parsing/test/test_ebnfparse.py @@ -103,6 +103,7 @@ """) parse = make_parse_function(regexs, rules) tree = parse("prefix(\n\tlonger(and_nested(term(X))), Xya, _, X0, _).") + assert tree.children[0].children[0].children[2].children[0].getsourcepos().lineno == 1 assert tree is not None tree = parse(""" foo(X, Y) :- bar(Y, X), bar(Y, X) ; foobar(X, Y, 1234, atom).""") diff --git a/pypy/rlib/parsing/tree.py b/pypy/rlib/parsing/tree.py --- a/pypy/rlib/parsing/tree.py +++ b/pypy/rlib/parsing/tree.py @@ -23,6 +23,9 @@ self.symbol = symbol self.additional_info = additional_info self.token = token + + def getsourcepos(self): + return self.token.source_pos def __repr__(self): return "Symbol(%r, %r)" % (self.symbol, self.additional_info) @@ -49,6 +52,9 @@ self.children = children self.symbol = symbol + def getsourcepos(self): + return self.children[0].getsourcepos() + def __str__(self): return "%s(%s)" % (self.symbol, ", ".join([str(c) for c in self.children])) diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py --- a/pypy/rlib/ropenssl.py +++ b/pypy/rlib/ropenssl.py @@ -3,8 +3,9 @@ from pypy.translator.platform import platform from pypy.translator.tool.cbuild import ExternalCompilationInfo -import sys +import sys, os +link_files = [] if sys.platform == 'win32' and platform.name != 'mingw32': libraries = ['libeay32', 'ssleay32', 'user32', 'advapi32', 'gdi32', 'msvcrt', 'ws2_32'] @@ -17,8 +18,17 @@ # so that openssl/ssl.h can repair this nonsense. 'wincrypt.h'] else: - libraries = ['ssl', 'crypto'] + libraries = ['z'] includes = [] + if (sys.platform.startswith('linux') and + os.path.exists('/usr/lib/libssl.a') and + os.path.exists('/usr/lib/libcrypto.a')): + # use static linking to avoid the infinite + # amount of troubles due to symbol versions + # and 0.9.8/1.0.0 + link_files += ['/usr/lib/libssl.a', '/usr/lib/libcrypto.a'] + else: + libraries += ['ssl', 'crypto'] includes += [ 'openssl/ssl.h', @@ -30,6 +40,7 @@ eci = ExternalCompilationInfo( libraries = libraries, + link_files = link_files, includes = includes, export_symbols = [], post_include_bits = [ diff --git a/pypy/rlib/rweakref.py b/pypy/rlib/rweakref.py --- a/pypy/rlib/rweakref.py +++ b/pypy/rlib/rweakref.py @@ -9,6 +9,9 @@ ref = weakref.ref # basic regular weakrefs are supported in RPython +def has_weakref_support(): + return True # returns False if --no-translation-rweakref + class RWeakValueDictionary(object): """A dictionary containing weak values.""" @@ -68,6 +71,20 @@ from pypy.annotation.bookkeeper import getbookkeeper from pypy.tool.pairtype import pairtype +class Entry(extregistry.ExtRegistryEntry): + _about_ = has_weakref_support + + def compute_result_annotation(self): + translator = self.bookkeeper.annotator.translator + res = translator.config.translation.rweakref + return self.bookkeeper.immutablevalue(res) + + def specialize_call(self, hop): + from pypy.rpython.lltypesystem import lltype + hop.exception_cannot_occur() + return hop.inputconst(lltype.Bool, hop.s_result.const) + + class SomeWeakValueDict(annmodel.SomeObject): knowntype = RWeakValueDictionary diff --git a/pypy/rlib/test/test_rweakref.py b/pypy/rlib/test/test_rweakref.py new file mode 100644 --- /dev/null +++ b/pypy/rlib/test/test_rweakref.py @@ -0,0 +1,14 @@ +from pypy.rlib.rweakref import has_weakref_support +from pypy.rpython.test.test_llinterp import interpret + + +def test_has_weakref_support(): + assert has_weakref_support() + + res = interpret(lambda: has_weakref_support(), [], + **{'translation.rweakref': True}) + assert res == True + + res = interpret(lambda: has_weakref_support(), [], + **{'translation.rweakref': False}) + assert res == False diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py --- a/pypy/rpython/module/ll_os.py +++ b/pypy/rpython/module/ll_os.py @@ -1174,8 +1174,11 @@ DIRENTP = lltype.Ptr(DIRENT) os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP, compilation_info=compilation_info) + # XXX macro=True is hack to make sure we get the correct kind of + # dirent struct (which depends on defines) os_readdir = self.llexternal('readdir', [DIRP], DIRENTP, - compilation_info=compilation_info) + compilation_info=compilation_info, + macro=True) os_closedir = self.llexternal('closedir', [DIRP], rffi.INT, compilation_info=compilation_info) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit