Author: Antonio Cuni <[email protected]>
Branch:
Changeset: r54452:afff86e02d5b
Date: 2012-04-17 11:11 +0200
http://bitbucket.org/pypy/pypy/changeset/afff86e02d5b/
Log: merge heads
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/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/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
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit