[pypy-svn] pypy fast-forward: merge default
amauryfa
commits-noreply at bitbucket.org
Sun Dec 26 22:21:47 CET 2010
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: fast-forward
Changeset: r40231:a73de8a29ef3
Date: 2010-12-26 22:21 +0100
http://bitbucket.org/pypy/pypy/changeset/a73de8a29ef3/
Log: merge default
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -105,14 +105,11 @@
make_sure_not_resized(self.arguments_w)
if w_stararg is not None:
self._combine_starargs_wrapped(w_stararg)
- if w_starstararg is not None:
- self._combine_starstarargs_wrapped(w_starstararg)
- # if we have a call where **args are used at the callsite
- # we shouldn't let the JIT see the argument matching
- self._dont_jit = True
- else:
- self._dont_jit = False
-
+ # if we have a call where **args are used at the callsite
+ # we shouldn't let the JIT see the argument matching
+ self._dont_jit = (w_starstararg is not None and
+ self._combine_starstarargs_wrapped(w_starstararg))
+
def __repr__(self):
""" NOT_RPYTHON """
name = self.__class__.__name__
@@ -171,6 +168,14 @@
"a mapping, not %s" % (typename,)))
raise
keys_w = space.unpackiterable(w_keys)
+ if keys_w:
+ self._do_combine_starstarargs_wrapped(keys_w, w_starstararg)
+ return True
+ else:
+ return False # empty dict; don't disable the JIT
+
+ def _do_combine_starstarargs_wrapped(self, keys_w, w_starstararg):
+ space = self.space
keywords_w = [None] * len(keys_w)
keywords = [None] * len(keys_w)
i = 0
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -939,7 +939,9 @@
if os.sep not in path:
path = os.curdir + os.sep + path # force a '/' in the path
state = space.fromcache(State)
- state.package_context = name
+ if state.find_extension(name, path) is not None:
+ return
+ state.package_context = name, path
try:
from pypy.rlib import rdynload
try:
@@ -964,7 +966,8 @@
generic_cpy_call(space, initfunc)
state.check_and_raise_exception()
finally:
- state.package_context = None
+ state.package_context = None, None
+ state.fixup_extension(name, path)
@specialize.ll()
def generic_cpy_call(space, func, *args):
diff --git a/pypy/module/cpyext/intobject.py b/pypy/module/cpyext/intobject.py
--- a/pypy/module/cpyext/intobject.py
+++ b/pypy/module/cpyext/intobject.py
@@ -95,4 +95,3 @@
if pend:
pend[0] = rffi.ptradd(str, len(s))
return space.call_function(space.w_int, w_str, w_base)
-
diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -292,7 +292,7 @@
def buffer_encode(space, s, errors='strict'):
return space.newtuple([space.wrap(s), space.wrap(len(s))])
-buffer_encode.unwrap_spec = [ObjSpace, 'bufferstr', str]
+buffer_encode.unwrap_spec = [ObjSpace, 'bufferstr', 'str_or_None']
def decode(space, w_obj, w_encoding=NoneNotWrapped, errors='strict'):
"""decode(obj, [encoding[,errors]]) -> object
@@ -380,18 +380,22 @@
rname = "unicode_encode_%s" % (name.replace("_encode", ""), )
assert hasattr(runicode, rname)
def wrap_encoder(space, uni, errors="strict"):
+ if errors is None:
+ errors = 'strict'
state = space.fromcache(CodecState)
func = getattr(runicode, rname)
result = func(uni, len(uni), errors, state.encode_error_handler)
return space.newtuple([space.wrap(result), space.wrap(len(uni))])
wrap_encoder.func_name = rname
- wrap_encoder.unwrap_spec = [ObjSpace, unicode, str]
+ wrap_encoder.unwrap_spec = [ObjSpace, unicode, 'str_or_None']
globals()[name] = wrap_encoder
def make_decoder_wrapper(name):
rname = "str_decode_%s" % (name.replace("_decode", ""), )
assert hasattr(runicode, rname)
def wrap_decoder(space, string, errors="strict", w_final=False):
+ if errors is None:
+ errors = 'strict'
final = space.is_true(w_final)
state = space.fromcache(CodecState)
func = getattr(runicode, rname)
@@ -399,7 +403,7 @@
final, state.decode_error_handler)
return space.newtuple([space.wrap(result), space.wrap(consumed)])
wrap_decoder.func_name = rname
- wrap_decoder.unwrap_spec = [ObjSpace, 'bufferstr', str, W_Root]
+ wrap_decoder.unwrap_spec = [ObjSpace, 'bufferstr', 'str_or_None', W_Root]
globals()[name] = wrap_decoder
for encoders in [
@@ -439,6 +443,8 @@
make_decoder_wrapper('mbcs_decode')
def utf_16_ex_decode(space, data, errors='strict', byteorder=0, w_final=False):
+ if errors is None:
+ errors = 'strict'
final = space.is_true(w_final)
state = space.fromcache(CodecState)
if byteorder == 0:
@@ -454,7 +460,7 @@
data, len(data), errors, final, state.decode_error_handler, byteorder)
return space.newtuple([space.wrap(res), space.wrap(consumed),
space.wrap(byteorder)])
-utf_16_ex_decode.unwrap_spec = [ObjSpace, str, str, int, W_Root]
+utf_16_ex_decode.unwrap_spec = [ObjSpace, str, 'str_or_None', int, W_Root]
def utf_32_ex_decode(space, data, errors='strict', byteorder=0, w_final=False):
final = space.is_true(w_final)
@@ -575,8 +581,10 @@
raise OperationError(space.w_TypeError, space.wrap("invalid mapping"))
- at unwrap_spec(ObjSpace, str, str, W_Root)
+ at unwrap_spec(ObjSpace, str, 'str_or_None', W_Root)
def charmap_decode(space, string, errors="strict", w_mapping=None):
+ if errors is None:
+ errors = 'strict'
if len(string) == 0:
return space.newtuple([space.wrap(u''), space.wrap(0)])
@@ -592,8 +600,10 @@
final, state.decode_error_handler, mapping)
return space.newtuple([space.wrap(result), space.wrap(consumed)])
- at unwrap_spec(ObjSpace, unicode, str, W_Root)
+ at unwrap_spec(ObjSpace, unicode, 'str_or_None', W_Root)
def charmap_encode(space, uni, errors="strict", w_mapping=None):
+ if errors is None:
+ errors = 'strict'
if space.is_w(w_mapping, space.w_None):
mapping = None
else:
@@ -633,8 +643,10 @@
return -1
return space.int_w(w_code)
- at unwrap_spec(ObjSpace, 'bufferstr', str, W_Root)
+ at unwrap_spec(ObjSpace, 'bufferstr', 'str_or_None', W_Root)
def unicode_escape_decode(space, string, errors="strict", w_final=False):
+ if errors is None:
+ errors = 'strict'
final = space.is_true(w_final)
state = space.fromcache(CodecState)
errorhandler=state.decode_error_handler
@@ -651,8 +663,10 @@
# ____________________________________________________________
# Unicode-internal
- at unwrap_spec(ObjSpace, W_Root, str)
+ at unwrap_spec(ObjSpace, W_Root, 'str_or_None')
def unicode_internal_decode(space, w_string, errors="strict"):
+ if errors is None:
+ errors = 'strict'
# special case for this codec: unicodes are returned as is
if space.isinstance_w(w_string, space.w_unicode):
return space.newtuple([w_string, space.len(w_string)])
@@ -673,13 +687,13 @@
# support for the "string escape" codec
# This is a bytes-to bytes transformation
- at unwrap_spec(ObjSpace, W_Root, str)
+ at unwrap_spec(ObjSpace, W_Root, 'str_or_None')
def escape_encode(space, w_string, errors='strict'):
w_repr = space.repr(w_string)
w_result = space.getslice(w_repr, space.wrap(1), space.wrap(-1))
return space.newtuple([w_result, space.len(w_string)])
- at unwrap_spec(ObjSpace, str, str)
+ at unwrap_spec(ObjSpace, str, 'str_or_None')
def escape_decode(space, data, errors='strict'):
from pypy.interpreter.pyparser.parsestring import PyString_DecodeEscape
result = PyString_DecodeEscape(space, data, None)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -380,14 +380,18 @@
return op
def make_args_key(self, op):
- args = []
- for i in range(op.numargs()):
+ n = op.numargs()
+ args = [None] * (n + 1)
+ for i in range(n):
arg = op.getarg(i)
- if arg in self.values:
- args.append(self.values[arg].get_key_box())
+ try:
+ value = self.values[arg]
+ except KeyError:
+ pass
else:
- args.append(arg)
- args.append(ConstInt(op.getopnum()))
+ arg = value.get_key_box()
+ args[i] = arg
+ args[n] = ConstInt(op.getopnum())
return args
def optimize_default(self, op):
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -387,8 +387,7 @@
from pypy.annotation import model as annmodel
if self.instance.__name__ == 'jit_merge_point':
- if not self.annotate_hooks(**kwds_s):
- return None # wrong order, try again later
+ self.annotate_hooks(**kwds_s)
driver = self.instance.im_self
keys = kwds_s.keys()
@@ -424,13 +423,13 @@
driver = self.instance.im_self
s_jitcell = self.bookkeeper.valueoftype(BaseJitCell)
h = self.annotate_hook
- return (h(driver.get_jitcell_at, driver.greens, **kwds_s)
- and h(driver.set_jitcell_at, driver.greens, [s_jitcell], **kwds_s)
- and h(driver.get_printable_location, driver.greens, **kwds_s))
+ h(driver.get_jitcell_at, driver.greens, **kwds_s)
+ h(driver.set_jitcell_at, driver.greens, [s_jitcell], **kwds_s)
+ h(driver.get_printable_location, driver.greens, **kwds_s)
def annotate_hook(self, func, variables, args_s=[], **kwds_s):
if func is None:
- return True
+ return
bk = self.bookkeeper
s_func = bk.immutablevalue(func)
uniquekey = 'jitdriver.%s' % func.func_name
@@ -441,12 +440,13 @@
else:
objname, fieldname = name.split('.')
s_instance = kwds_s['s_' + objname]
- s_arg = s_instance.classdef.about_attribute(fieldname)
- if s_arg is None:
- return False # wrong order, try again later
+ attrdef = s_instance.classdef.find_attribute(fieldname)
+ position = self.bookkeeper.position_key
+ attrdef.read_locations[position] = True
+ s_arg = attrdef.getvalue()
+ assert s_arg is not None
args_s.append(s_arg)
bk.emulate_pbc_call(uniquekey, s_func, args_s)
- return True
def specialize_call(self, hop, **kwds_i):
# XXX to be complete, this could also check that the concretetype
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -213,12 +213,14 @@
stream.truncate(size)
def direct_write(self, data):
+ self.softspace = 0
self.getstream().write(data)
def direct_writelines(self, w_lines): # note: a wrapped list!
stream = self.getstream()
space = self.space
w_iterator = space.iter(w_lines)
+ self.softspace = 0
while True:
try:
w_line = space.next(w_iterator)
diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py
--- a/pypy/module/sys/version.py
+++ b/pypy/module/sys/version.py
@@ -9,7 +9,7 @@
CPYTHON_VERSION = (2, 7, 0, "final", 42) #XXX # sync patchlevel.h
CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h
-PYPY_VERSION = (1, 4, 0, "beta", 0) #XXX # sync patchlevel.h
+PYPY_VERSION = (1, 4, 1, "beta", 0) #XXX # sync patchlevel.h
if platform.name == 'msvc':
COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600)
diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py
--- a/pypy/module/cpyext/test/test_longobject.py
+++ b/pypy/module/cpyext/test/test_longobject.py
@@ -1,4 +1,4 @@
-import sys
+import sys, py
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.longobject import W_LongObject
@@ -97,6 +97,10 @@
assert api.PyLong_AsVoidPtr(w_l) == lltype.nullptr(rffi.VOIDP_real.TO)
def test_sign_and_bits(self, space, api):
+ if space.is_true(space.lt(space.sys.get('version_info'),
+ space.wrap((2, 7)))):
+ py.test.skip("unsupported before Python 2.7")
+
assert api._PyLong_Sign(space.wrap(0L)) == 0
assert api._PyLong_Sign(space.wrap(2L)) == 1
assert api._PyLong_Sign(space.wrap(-2L)) == -1
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -16,14 +16,19 @@
self.operror = None
self.new_method_def = lltype.nullptr(PyMethodDef)
- # When importing a package, use this to keep track of its name. This is
+ # When importing a package, use this to keep track
+ # of its name and path (as a 2-tuple). This is
# necessary because an extension module in a package might not supply
# its own fully qualified name to Py_InitModule. If it doesn't, we need
# to be able to figure out what module is being initialized. Recursive
# imports will clobber this value, which might be confusing, but it
# doesn't hurt anything because the code that cares about it will have
# already read it by that time.
- self.package_context = None
+ self.package_context = None, None
+
+ # A mapping {filename: copy-of-the-w_dict}, similar to CPython's
+ # variable 'extensions' in Python/import.c.
+ self.extensions = {}
def set_exception(self, operror):
self.clear_exception()
@@ -96,3 +101,29 @@
self.programname = rffi.str2charp(progname)
lltype.render_immortal(self.programname)
return self.programname
+
+ def find_extension(self, name, path):
+ from pypy.module.cpyext.modsupport import PyImport_AddModule
+ from pypy.interpreter.module import Module
+ try:
+ w_dict = self.extensions[path]
+ except KeyError:
+ return None
+ w_mod = PyImport_AddModule(self.space, name)
+ assert isinstance(w_mod, Module)
+ w_mdict = w_mod.getdict()
+ self.space.call_method(w_mdict, 'update', w_dict)
+ return w_mod
+
+ def fixup_extension(self, name, path):
+ from pypy.interpreter.module import Module
+ space = self.space
+ w_modules = space.sys.get('modules')
+ w_mod = space.finditem_str(w_modules, name)
+ if not isinstance(w_mod, Module):
+ msg = "fixup_extension: module '%s' not loaded" % name
+ raise OperationError(space.w_SystemError,
+ space.wrap(msg))
+ w_dict = w_mod.getdict()
+ w_copy = space.call_method(w_dict, 'copy')
+ self.extensions[path] = w_copy
diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -95,6 +95,22 @@
assert obj.char_member == "a"
raises(TypeError, "obj.char_member = 'spam'")
raises(TypeError, "obj.char_member = 42")
+ #
+ import sys
+ bignum = sys.maxint - 42
+ obj.short_member = -12345; assert obj.short_member == -12345
+ obj.long_member = -bignum; assert obj.long_member == -bignum
+ obj.ushort_member = 45678; assert obj.ushort_member == 45678
+ obj.uint_member = 3000000000; assert obj.uint_member == 3000000000
+ obj.ulong_member = 2*bignum; assert obj.ulong_member == 2*bignum
+ obj.byte_member = -99; assert obj.byte_member == -99
+ obj.ubyte_member = 199; assert obj.ubyte_member == 199
+ obj.bool_member = True; assert obj.bool_member is True
+ obj.float_member = 9.25; assert obj.float_member == 9.25
+ obj.double_member = 9.25; assert obj.double_member == 9.25
+ obj.longlong_member = -2**59; assert obj.longlong_member == -2**59
+ obj.ulonglong_member = 2**63; assert obj.ulonglong_member == 2**63
+ #
self.cleanup_references()
def test_staticmethod(self):
diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py
--- a/pypy/interpreter/test/test_interpreter.py
+++ b/pypy/interpreter/test/test_interpreter.py
@@ -156,6 +156,21 @@
'''
self.codetest(code, 'f', [])
+ def test_import_default_arg(self):
+ # CPython does not always call __import__() with 5 arguments,
+ # but only if the 5th one is not -1.
+ real_call_function = self.space.call_function
+ space = self.space
+ def safe_call_function(w_obj, *arg_w):
+ assert not arg_w or not space.eq_w(arg_w[-1], space.wrap(-1))
+ return real_call_function(w_obj, *arg_w)
+ self.space.call_function = safe_call_function
+ code = '''
+ def f():
+ import sys
+ '''
+ self.codetest(code, 'f', [])
+
def test_call_star_starstar(self):
code = '''\
def f1(n):
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -78,7 +78,13 @@
old_dir = os.getcwd()
try:
os.chdir(str(builddir))
- os.system("strip -x " + str(archive_pypy_c)) # ignore errors
+ #
+ # 'strip' fun: see https://codespeak.net/issue/pypy-dev/issue587
+ if sys.platform == 'darwin':
+ os.system("strip -x " + str(archive_pypy_c)) # ignore errors
+ else:
+ os.system("strip " + str(archive_pypy_c)) # ignore errors
+ #
if USE_TARFILE_MODULE:
import tarfile
tf = tarfile.open(str(builddir.join(name + '.tar.bz2')), 'w:bz2')
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -167,6 +167,9 @@
if not we_are_translated():
metainterp_sd.stats.compiled()
metainterp_sd.log("compiled new bridge")
+ if metainterp_sd.warmrunnerdesc is not None: # for tests
+ metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(
+ original_loop_token)
# ____________________________________________________________
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -692,8 +692,12 @@
def test_mknod(self):
import stat
os = self.posix
- # not very useful: os.mknod() without specifying 'mode'
- os.mknod(self.path2 + 'test_mknod-1')
+ # os.mknod() may require root priviledges to work at all
+ try:
+ # not very useful: os.mknod() without specifying 'mode'
+ os.mknod(self.path2 + 'test_mknod-1')
+ except OSError, e:
+ skip("os.mknod(): got %r" % (e,))
st = os.lstat(self.path2 + 'test_mknod-1')
assert stat.S_ISREG(st.st_mode)
# os.mknod() with S_IFIFO
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1122,6 +1122,11 @@
buffer = self.buffer_w(w_obj)
return buffer.as_str()
+ def str_or_None_w(self, w_obj):
+ if self.is_w(w_obj, self.w_None):
+ return None
+ return self.str_w(w_obj)
+
def realstr_w(self, w_obj):
# Like str_w, but only works if w_obj is really of type 'str'.
if not self.is_true(self.isinstance(w_obj, self.w_str)):
diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py
--- a/pypy/module/_file/test/test_file.py
+++ b/pypy/module/_file/test/test_file.py
@@ -174,7 +174,18 @@
raises(ValueError, self.file, self.temppath, "aU")
raises(ValueError, self.file, self.temppath, "wU+")
raises(ValueError, self.file, self.temppath, "")
-
+
+ def test_write_resets_softspace(self):
+ f = self.file(self.temppath, "w")
+ print >> f, '.',
+ f.write(',')
+ print >> f, '.',
+ f.close()
+ f = self.file(self.temppath, "r")
+ res = f.read()
+ assert res == ".,."
+ f.close()
+
class AppTestConcurrency(object):
# these tests only really make sense on top of a translated pypy-c,
# because on top of py.py the inner calls to os.write() don't
diff --git a/pypy/module/cpyext/test/test_memoryobject.py b/pypy/module/cpyext/test/test_memoryobject.py
--- a/pypy/module/cpyext/test/test_memoryobject.py
+++ b/pypy/module/cpyext/test/test_memoryobject.py
@@ -1,7 +1,12 @@
+import py
from pypy.module.cpyext.test.test_api import BaseApiTest
class TestMemoryViewObject(BaseApiTest):
def test_fromobject(self, space, api):
+ if space.is_true(space.lt(space.sys.get('version_info'),
+ space.wrap((2, 7)))):
+ py.test.skip("unsupported before Python 2.7")
+
w_hello = space.wrap("hello")
w_view = api.PyMemoryView_FromObject(w_hello)
w_bytes = space.call_method(w_view, "tobytes")
diff --git a/pypy/jit/backend/x86/test/test_ztranslation.py b/pypy/jit/backend/x86/test/test_ztranslation.py
--- a/pypy/jit/backend/x86/test/test_ztranslation.py
+++ b/pypy/jit/backend/x86/test/test_ztranslation.py
@@ -189,14 +189,14 @@
@dont_look_inside
def f(x, total):
- if x <= 3:
+ if x <= 30:
raise ImDone(total * 10)
- if x > 20:
+ if x > 200:
return 2
raise ValueError
@dont_look_inside
def g(x):
- if x > 15:
+ if x > 150:
raise ValueError
return 2
class Base:
@@ -207,7 +207,7 @@
return 1
@dont_look_inside
def h(x):
- if x < 2000:
+ if x < 20000:
return Sub()
else:
return Base()
@@ -238,8 +238,8 @@
logfile = udir.join('test_ztranslation.log')
os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,)
try:
- res = self.meta_interp(main, [40])
- assert res == main(40)
+ res = self.meta_interp(main, [400])
+ assert res == main(400)
finally:
del os.environ['PYPYLOG']
@@ -248,5 +248,7 @@
if 'guard_class' in line:
guard_class += 1
# if we get many more guard_classes, it means that we generate
- # guards that always fail
- assert 0 < guard_class <= 4
+ # guards that always fail (the following assert's original purpose
+ # is to catch the following case: each GUARD_CLASS is misgenerated
+ # and always fails with "gcremovetypeptr")
+ assert 0 < guard_class < 10
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -46,6 +46,8 @@
def test_dllhandle(self):
import sys
+ if sys.version_info < (2, 6):
+ skip("Python >= 2.6 only")
assert sys.dllhandle
assert sys.dllhandle.getaddressindll('PyPyErr_NewException')
import ctypes # slow
@@ -220,6 +222,12 @@
else:
return os.path.dirname(mod)
+ def reimport_module(self, mod, name):
+ api.load_extension_module(self.space, mod, name)
+ return self.space.getitem(
+ self.space.sys.get('modules'),
+ self.space.wrap(name))
+
def import_extension(self, modname, functions, prologue=""):
methods_table = []
codes = []
@@ -259,6 +267,7 @@
self.imported_module_names = []
self.w_import_module = self.space.wrap(self.import_module)
+ self.w_reimport_module = self.space.wrap(self.reimport_module)
self.w_import_extension = self.space.wrap(self.import_extension)
self.w_compile_module = self.space.wrap(self.compile_module)
self.w_record_imported_module = self.space.wrap(
@@ -707,3 +716,43 @@
p = mod.get_programname()
print p
assert 'py' in p
+
+ def test_no_double_imports(self):
+ import sys, os
+ try:
+ init = """
+ static int _imported_already = 0;
+ FILE *f = fopen("_imported_already", "w");
+ fprintf(f, "imported_already: %d\\n", _imported_already);
+ fclose(f);
+ _imported_already = 1;
+ if (Py_IsInitialized()) {
+ Py_InitModule("foo", NULL);
+ }
+ """
+ self.import_module(name='foo', init=init)
+ assert 'foo' in sys.modules
+
+ f = open('_imported_already')
+ data = f.read()
+ f.close()
+ assert data == 'imported_already: 0\n'
+
+ f = open('_imported_already', 'w')
+ f.write('not again!\n')
+ f.close()
+ m1 = sys.modules['foo']
+ m2 = self.reimport_module(m1.__file__, name='foo')
+ assert m1 is m2
+ assert m1 is sys.modules['foo']
+
+ f = open('_imported_already')
+ data = f.read()
+ f.close()
+ assert data == 'not again!\n'
+
+ finally:
+ try:
+ os.unlink('_imported_already')
+ except OSError:
+ pass
diff --git a/pypy/tool/release/make_release.py b/pypy/tool/release/make_release.py
--- a/pypy/tool/release/make_release.py
+++ b/pypy/tool/release/make_release.py
@@ -4,7 +4,8 @@
into release packages. Note: you must run apropriate buildbots first and
make sure there are no failures. Use force-builds.py from the same directory.
-Usage: make_release.py release/<release name> release_version
+Usage: make_release.py <branchname> <version>
+ e.g.: make_release.py release-1.4.1 1.4.1
"""
import autopath
@@ -20,6 +21,7 @@
import shutil
BASEURL = 'http://buildbot.pypy.org/nightly/'
+PAUSE = False
def browse_nightly(branch,
baseurl=BASEURL,
@@ -32,12 +34,12 @@
dom = minidom.parseString(xml)
refs = [node.getAttribute('href') for node in dom.getElementsByTagName('a')
if 'pypy' in node.getAttribute('href')]
- # all refs are of form: pypy-{type}-{revision}-{platform}.tar.bz2
- r = re.compile('pypy-c-([\w\d]+)-(\d+)-([\w\d]+).tar.bz2$')
+ # all refs are of form: pypy-c-{type}-{revnum}-{hghash}-{platform}.tar.bz2
+ r = re.compile('pypy-c-([\w\d]+)-(\d+)-([0-9a-f]+)-([\w\d]+).tar.bz2$')
d = {}
for ref in refs:
- kind, rev, platform = r.match(ref).groups()
- rev = int(rev)
+ kind, revnum, hghash, platform = r.match(ref).groups()
+ rev = int(revnum)
try:
lastrev, _ = d[(kind, platform)]
except KeyError:
@@ -51,8 +53,10 @@
tmpdir = udir.join('download')
tmpdir.ensure(dir=True)
alltars = []
+ olddir = os.getcwd()
try:
os.chdir(str(tmpdir))
+ print 'Using tmpdir', str(tmpdir)
for (kind, platform), (rev, name) in to_download.iteritems():
if platform == 'win32':
print 'Ignoring %s, windows unsupported' % name
@@ -64,20 +68,23 @@
t = tarfile.open(str(tmpdir.join(name)))
dirname = t.getmembers()[0].name
t.extractall(path=str(tmpdir))
- os.system('mv %s %s' % (str(tmpdir.join(dirname)),
- str(tmpdir.join('pypy-%s' % release))))
if kind == 'jit':
kind = ''
else:
kind = '-' + kind
- olddir = os.getcwd()
- name = 'pypy-%s-%s%s.tar.bz2' % (release, platform, kind)
+ topdirname = 'pypy-%s-%s%s' % (release, platform, kind)
+ os.system('mv %s %s' % (str(tmpdir.join(dirname)),
+ str(tmpdir.join(topdirname))))
+ if PAUSE:
+ print 'Pausing, press Enter...'
+ raw_input()
+ name = '%s.tar.bz2' % topdirname
print "Building %s" % name
t = tarfile.open(name, 'w:bz2')
- t.add('pypy-%s' % release)
+ t.add(topdirname)
alltars.append(name)
t.close()
- shutil.rmtree(str(tmpdir.join('pypy-' + release)))
+ shutil.rmtree(str(tmpdir.join(topdirname)))
for name in alltars:
print "Uploading %s" % name
os.system('scp %s codespeak.net:/www/pypy.org/htdocs/download' % name)
More information about the Pypy-commit
mailing list