[pypy-commit] pypy release-2.6.x: merge default into release
mattip
noreply at buildbot.pypy.org
Thu May 28 16:15:01 CEST 2015
Author: mattip <matti.picus at gmail.com>
Branch: release-2.6.x
Changeset: r77653:e03971291f3a
Date: 2015-05-28 17:14 +0300
http://bitbucket.org/pypy/pypy/changeset/e03971291f3a/
Log: merge default into release
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
@@ -505,7 +505,7 @@
"modules")
mkpath(tmpdir)
ext, updated = recompile(self, module_name,
- source, tmpdir=tmpdir,
+ source, tmpdir=tmpdir, extradir=tmpdir,
source_extension=source_extension,
call_c_compiler=False, **kwds)
if verbose:
diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py
--- a/lib_pypy/cffi/recompiler.py
+++ b/lib_pypy/cffi/recompiler.py
@@ -1148,8 +1148,14 @@
raise IOError
return False # already up-to-date
except IOError:
- with open(target_file, 'w') as f1:
+ tmp_file = '%s.~%d' % (target_file, os.getpid())
+ with open(tmp_file, 'w') as f1:
f1.write(output)
+ try:
+ os.rename(tmp_file, target_file)
+ except OSError:
+ os.unlink(target_file)
+ os.rename(tmp_file, target_file)
return True
def make_c_source(ffi, module_name, preamble, target_c_file):
@@ -1169,7 +1175,7 @@
return os.path.join(outputdir, *parts), parts
def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True,
- c_file=None, source_extension='.c', **kwds):
+ c_file=None, source_extension='.c', extradir=None, **kwds):
if not isinstance(module_name, str):
module_name = module_name.encode('ascii')
if ffi._windows_unicode:
@@ -1178,6 +1184,8 @@
if c_file is None:
c_file, parts = _modname_to_file(tmpdir, module_name,
source_extension)
+ if extradir:
+ parts = [extradir] + parts
ext_c_file = os.path.join(*parts)
else:
ext_c_file = c_file
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -108,13 +108,11 @@
def _add_py_module(dist, ffi, module_name):
from distutils.dir_util import mkpath
from distutils.command.build_py import build_py
+ from distutils.command.build_ext import build_ext
from distutils import log
from cffi import recompiler
- def make_mod(tmpdir):
- module_path = module_name.split('.')
- module_path[-1] += '.py'
- py_file = os.path.join(tmpdir, *module_path)
+ def generate_mod(py_file):
log.info("generating cffi module %r" % py_file)
mkpath(os.path.dirname(py_file))
updated = recompiler.make_py_source(ffi, module_name, py_file)
@@ -125,9 +123,25 @@
class build_py_make_mod(base_class):
def run(self):
base_class.run(self)
- make_mod(self.build_lib)
+ module_path = module_name.split('.')
+ module_path[-1] += '.py'
+ generate_mod(os.path.join(self.build_lib, *module_path))
dist.cmdclass['build_py'] = build_py_make_mod
+ # the following is only for "build_ext -i"
+ base_class_2 = dist.cmdclass.get('build_ext', build_ext)
+ class build_ext_make_mod(base_class_2):
+ def run(self):
+ base_class_2.run(self)
+ if self.inplace:
+ # from get_ext_fullpath() in distutils/command/build_ext.py
+ module_path = module_name.split('.')
+ package = '.'.join(module_path[:-1])
+ build_py = self.get_finalized_command('build_py')
+ package_dir = build_py.get_package_dir(package)
+ file_name = module_path[-1] + '.py'
+ generate_mod(os.path.join(package_dir, file_name))
+ dist.cmdclass['build_ext'] = build_ext_make_mod
def cffi_modules(dist, attr, value):
assert attr == 'cffi_modules'
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -321,7 +321,7 @@
def enable_allworkingmodules(config):
- modules = working_modules
+ modules = working_modules.copy()
if config.translation.sandbox:
modules = default_modules
# ignore names from 'essential_modules', notably 'exceptions', which
diff --git a/pypy/doc/config/objspace.usemodules._vmprof.txt b/pypy/doc/config/objspace.usemodules._vmprof.txt
new file mode 100644
diff --git a/pypy/doc/config/translation.icon.txt b/pypy/doc/config/translation.icon.txt
new file mode 100644
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -16,40 +16,44 @@
-------------
* At code freeze make a release branch using release-x.x.x in mercurial
- Bump the
+ and add a release-specific tag
+* Bump the
pypy version number in module/sys/version.py and in
- module/cpyext/include/patchlevel.h. The branch
+ module/cpyext/include/patchlevel.h and . The branch
will capture the revision number of this change for the release.
+
Some of the next updates may be done before or after branching; make
sure things are ported back to the trunk and to the branch as
- necessary; also update the version number in pypy/doc/conf.py.
+ necessary.
* update pypy/doc/contributor.rst (and possibly LICENSE)
pypy/doc/tool/makecontributor.py generates the list of contributors
* rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst
create a fresh whatsnew_head.rst after the release
and add the new file to pypy/doc/index-of-whatsnew.rst
-* go to pypy/tool/release and run:
- force-builds.py <release branch>
-
- The following binaries should be built, however, we need more buildbots:
- JIT: windows, linux, os/x, armhf, armel
- no JIT: windows, linux, os/x
- sandbox: linux, os/x
+* go to pypy/tool/release and run
+ ``force-builds.py <release branch>``
+ The following binaries should be built, however, we need more buildbots
+ - JIT: windows, linux, os/x, armhf, armel
+ - no JIT: windows, linux, os/x
+ - sandbox: linux, os/x
* wait for builds to complete, make sure there are no failures
* download the builds, repackage binaries. Tag the release version
and download and repackage source from bitbucket. You may find it
- convenient to use the repackage.sh script in pypy/tools to do this.
- Otherwise, repackage and upload source "-src.tar.bz2" to bitbucket
+ convenient to use the ``repackage.sh`` script in pypy/tools to do this.
+
+ Otherwise repackage and upload source "-src.tar.bz2" to bitbucket
and to cobra, as some packagers prefer a clearly labeled source package
- (download e.g. https://bitbucket.org/pypy/pypy/get/release-2.5.x.tar.bz2,
+ ( download e.g. https://bitbucket.org/pypy/pypy/get/release-2.5.x.tar.bz2,
unpack, rename the top-level directory to "pypy-2.5.0-src", repack, and upload)
* Upload binaries to https://bitbucket.org/pypy/pypy/downloads
* write release announcement pypy/doc/release-x.y(.z).txt
- the release announcement should contain a direct link to the download page
- and add new files to pypy/doc/index-of-release-notes.rst
+
+ The release announcement should contain a direct link to the download page
+
+* Add the new files to pypy/doc/index-of-{whatsnew,release-notes}.rst
* update pypy.org (under extradoc/pypy.org), rebuild and commit
@@ -59,4 +63,5 @@
* add a tag on the pypy/jitviewer repo that corresponds to pypy release
* add a tag on the codespeed web site that corresponds to pypy release
+* update the version number in {rpython,pypy}/doc/conf.py.
* revise versioning at https://readthedocs.org/projects/pypy
diff --git a/pypy/module/_cffi_backend/lib_obj.py b/pypy/module/_cffi_backend/lib_obj.py
--- a/pypy/module/_cffi_backend/lib_obj.py
+++ b/pypy/module/_cffi_backend/lib_obj.py
@@ -131,9 +131,10 @@
g.c_address)
assert fetch_funcptr
assert w_ct.size > 0
- with lltype.scoped_alloc(rffi.CCHARP.TO, w_ct.size) as ptr:
- fetch_funcptr(ptr)
- w_result = w_ct.convert_to_object(ptr)
+ ptr = lltype.malloc(rffi.CCHARP.TO, w_ct.size, flavor='raw')
+ self.ffi._finalizer.free_mems.append(ptr)
+ fetch_funcptr(ptr)
+ w_result = w_ct.convert_to_object(ptr)
#
elif op == cffi_opcode.OP_DLOPEN_FUNC:
# For dlopen(): the function of the given 'name'. We use
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -66,6 +66,9 @@
""")
ffiobject = space.getitem(w_res, space.wrap(0))
ffiobject._test_recompiler_source_ffi = ffi
+ if not hasattr(space, '_cleanup_ffi'):
+ space._cleanup_ffi = []
+ space._cleanup_ffi.append(ffiobject)
return w_res
@@ -84,6 +87,10 @@
""")
def teardown_method(self, meth):
+ if hasattr(self.space, '_cleanup_ffi'):
+ for ffi in self.space._cleanup_ffi:
+ del ffi.cached_types # try to prevent cycles
+ del self.space._cleanup_ffi
self.space.appexec([self._w_modules], """(old_modules):
import sys
for key in sys.modules.keys():
@@ -799,3 +806,46 @@
assert addr(0xABC05) == 47
assert isinstance(addr, ffi.CData)
assert ffi.typeof(addr) == ffi.typeof("long(*)(long)")
+
+ def test_issue198(self):
+ ffi, lib = self.prepare("""
+ typedef struct{...;} opaque_t;
+ const opaque_t CONSTANT;
+ int toint(opaque_t);
+ """, 'test_issue198', """
+ typedef int opaque_t;
+ #define CONSTANT ((opaque_t)42)
+ static int toint(opaque_t o) { return o; }
+ """)
+ def random_stuff():
+ pass
+ assert lib.toint(lib.CONSTANT) == 42
+ random_stuff()
+ assert lib.toint(lib.CONSTANT) == 42
+
+ def test_constant_is_not_a_compiler_constant(self):
+ ffi, lib = self.prepare(
+ "static const float almost_forty_two;",
+ 'test_constant_is_not_a_compiler_constant', """
+ static float f(void) { return 42.25; }
+ #define almost_forty_two (f())
+ """)
+ assert lib.almost_forty_two == 42.25
+
+ def test_variable_of_unknown_size(self):
+ ffi, lib = self.prepare("""
+ typedef ... opaque_t;
+ opaque_t globvar;
+ """, 'test_constant_of_unknown_size', """
+ typedef char opaque_t[6];
+ opaque_t globvar = "hello";
+ """)
+ # can't read or write it at all
+ e = raises(TypeError, getattr, lib, 'globvar')
+ assert str(e.value) == "'opaque_t' is opaque or not completed yet"
+ e = raises(TypeError, setattr, lib, 'globvar', [])
+ assert str(e.value) == "'opaque_t' is opaque or not completed yet"
+ # but we can get its address
+ p = ffi.addressof(lib, 'globvar')
+ assert ffi.typeof(p) == ffi.typeof('opaque_t *')
+ assert ffi.string(ffi.cast("char *", p), 8) == "hello"
diff --git a/pypy/module/_vmprof/src/fake_pypy_api.c b/pypy/module/_vmprof/src/fake_pypy_api.c
--- a/pypy/module/_vmprof/src/fake_pypy_api.c
+++ b/pypy/module/_vmprof/src/fake_pypy_api.c
@@ -1,21 +1,4 @@
-
-long pypy_jit_stack_depth_at_loc(long x)
-{
- return 0;
-}
-
-void *pypy_find_codemap_at_addr(long x)
-{
- return (void *)0;
-}
-
-long pypy_yield_codemap_at_addr(void *x, long y, long *a)
-{
- return 0;
-}
void pypy_pyframe_execute_frame(void)
{
}
-
-volatile int pypy_codemap_currently_invalid = 0;
diff --git a/pypy/module/_vmprof/src/get_custom_offset.c b/pypy/module/_vmprof/src/get_custom_offset.c
--- a/pypy/module/_vmprof/src/get_custom_offset.c
+++ b/pypy/module/_vmprof/src/get_custom_offset.c
@@ -1,3 +1,5 @@
+
+#ifdef PYPY_JIT_CODEMAP
extern volatile int pypy_codemap_currently_invalid;
@@ -6,6 +8,8 @@
long *current_pos_addr);
long pypy_jit_stack_depth_at_loc(long loc);
+#endif
+
void vmprof_set_tramp_range(void* start, void* end)
{
@@ -13,17 +17,26 @@
int custom_sanity_check()
{
+#ifdef PYPY_JIT_CODEMAP
return !pypy_codemap_currently_invalid;
+#else
+ return 1;
+#endif
}
static ptrdiff_t vmprof_unw_get_custom_offset(void* ip, void *cp) {
+#ifdef PYPY_JIT_CODEMAP
intptr_t ip_l = (intptr_t)ip;
return pypy_jit_stack_depth_at_loc(ip_l);
+#else
+ return 0;
+#endif
}
static long vmprof_write_header_for_jit_addr(void **result, long n,
void *ip, int max_depth)
{
+#ifdef PYPY_JIT_CODEMAP
void *codemap;
long current_pos = 0;
intptr_t id;
@@ -62,5 +75,6 @@
if (n < max_depth) {
result[n++] = (void*)3;
}
+#endif
return n;
}
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
@@ -1,5 +1,6 @@
# Generated by pypy/tool/import_cffi.py
import sys, os, py
+import subprocess
import cffi
from pypy.module.test_lib_pypy.cffi_tests.udir import udir
@@ -16,6 +17,9 @@
class TestDist(object):
def setup_method(self, meth):
+ self.executable = os.path.abspath(sys.executable)
+ self.rootdir = os.path.abspath(os.path.dirname(os.path.dirname(
+ cffi.__file__)))
self.udir = udir.join(meth.__name__)
os.mkdir(str(self.udir))
if meth.chdir_to_tmp:
@@ -26,6 +30,25 @@
if hasattr(self, 'saved_cwd'):
os.chdir(self.saved_cwd)
+ def run(self, args):
+ env = os.environ.copy()
+ newpath = self.rootdir
+ if 'PYTHONPATH' in env:
+ newpath += os.pathsep + env['PYTHONPATH']
+ env['PYTHONPATH'] = newpath
+ subprocess.check_call([self.executable] + args, env=env)
+
+ def _prepare_setuptools(self):
+ if hasattr(TestDist, '_setuptools_ready'):
+ return
+ try:
+ import setuptools
+ except ImportError:
+ py.test.skip("setuptools not found")
+ subprocess.check_call([self.executable, 'setup.py', 'egg_info'],
+ cwd=self.rootdir)
+ TestDist._setuptools_ready = True
+
def check_produced_files(self, content, curdir=None):
if curdir is None:
curdir = str(self.udir)
@@ -35,6 +58,8 @@
name.endswith('.dylib')):
found_so = os.path.join(curdir, name)
name = name.split('.')[0] + '.SO' # foo.cpython-34m.so => foo.SO
+ if name.startswith('pycparser') and name.endswith('.egg'):
+ continue # no clue why this shows up sometimes and not others
assert name in content, "found unexpected file %r" % (
os.path.join(curdir, name),)
value = content.pop(name)
@@ -172,3 +197,143 @@
'foo': {'mod_name_in_package': {'mymod.SO': None,
'mymod.c': None},
'Release': '?'}})
+
+ @chdir_to_tmp
+ def test_api_distutils_extension_1(self):
+ ffi = cffi.FFI()
+ ffi.set_source("mod_name_in_package.mymod", "/*code would be here*/")
+ ext = ffi.distutils_extension()
+ self.check_produced_files({'build': {
+ 'mod_name_in_package': {'mymod.c': None}}})
+ if hasattr(os.path, 'samefile'):
+ assert os.path.samefile(ext.sources[0],
+ 'build/mod_name_in_package/mymod.c')
+
+ @from_outside
+ def test_api_distutils_extension_2(self):
+ ffi = cffi.FFI()
+ ffi.set_source("mod_name_in_package.mymod", "/*code would be here*/")
+ ext = ffi.distutils_extension(str(self.udir.join('foo')))
+ self.check_produced_files({'foo': {
+ 'mod_name_in_package': {'mymod.c': None}}})
+ if hasattr(os.path, 'samefile'):
+ assert os.path.samefile(ext.sources[0],
+ str(self.udir.join('foo/mod_name_in_package/mymod.c')))
+
+
+ def _make_distutils_api(self):
+ os.mkdir("src")
+ os.mkdir(os.path.join("src", "pack1"))
+ with open(os.path.join("src", "pack1", "__init__.py"), "w") as f:
+ pass
+ with open("setup.py", "w") as f:
+ f.write("""if 1:
+ import cffi
+ ffi = cffi.FFI()
+ ffi.set_source("pack1.mymod", "/*code would be here*/")
+
+ from distutils.core import setup
+ setup(name='example1',
+ version='0.1',
+ packages=['pack1'],
+ package_dir={'': 'src'},
+ ext_modules=[ffi.distutils_extension()])
+ """)
+
+ @chdir_to_tmp
+ def test_distutils_api_1(self):
+ self._make_distutils_api()
+ self.run(["setup.py", "build"])
+ self.check_produced_files({'setup.py': None,
+ 'build': '?',
+ 'src': {'pack1': {'__init__.py': None}}})
+
+ @chdir_to_tmp
+ def test_distutils_api_2(self):
+ self._make_distutils_api()
+ self.run(["setup.py", "build_ext", "-i"])
+ self.check_produced_files({'setup.py': None,
+ 'build': '?',
+ 'src': {'pack1': {'__init__.py': None,
+ 'mymod.SO': None}}})
+
+ def _make_setuptools_abi(self):
+ self._prepare_setuptools()
+ os.mkdir("src0")
+ os.mkdir(os.path.join("src0", "pack2"))
+ with open(os.path.join("src0", "pack2", "__init__.py"), "w") as f:
+ pass
+ with open(os.path.join("src0", "pack2", "_build.py"), "w") as f:
+ f.write("""if 1:
+ import cffi
+ ffi = cffi.FFI()
+ ffi.set_source("pack2.mymod", None)
+ """)
+ with open("setup.py", "w") as f:
+ f.write("""if 1:
+ from setuptools import setup
+ setup(name='example1',
+ version='0.1',
+ packages=['pack2'],
+ package_dir={'': 'src0'},
+ cffi_modules=["src0/pack2/_build.py:ffi"])
+ """)
+
+ @chdir_to_tmp
+ def test_setuptools_abi_1(self):
+ self._make_setuptools_abi()
+ self.run(["setup.py", "build"])
+ self.check_produced_files({'setup.py': None,
+ 'build': '?',
+ 'src0': {'pack2': {'__init__.py': None,
+ '_build.py': None}}})
+
+ @chdir_to_tmp
+ def test_setuptools_abi_2(self):
+ self._make_setuptools_abi()
+ self.run(["setup.py", "build_ext", "-i"])
+ self.check_produced_files({'setup.py': None,
+ 'src0': {'pack2': {'__init__.py': None,
+ '_build.py': None,
+ 'mymod.py': None}}})
+
+ def _make_setuptools_api(self):
+ self._prepare_setuptools()
+ os.mkdir("src1")
+ os.mkdir(os.path.join("src1", "pack3"))
+ with open(os.path.join("src1", "pack3", "__init__.py"), "w") as f:
+ pass
+ with open(os.path.join("src1", "pack3", "_build.py"), "w") as f:
+ f.write("""if 1:
+ import cffi
+ ffi = cffi.FFI()
+ ffi.set_source("pack3.mymod", "/*code would be here*/")
+ """)
+ with open("setup.py", "w") as f:
+ f.write("""if 1:
+ from setuptools import setup
+ setup(name='example1',
+ version='0.1',
+ packages=['pack3'],
+ package_dir={'': 'src1'},
+ cffi_modules=["src1/pack3/_build.py:ffi"])
+ """)
+
+ @chdir_to_tmp
+ def test_setuptools_api_1(self):
+ self._make_setuptools_api()
+ self.run(["setup.py", "build"])
+ self.check_produced_files({'setup.py': None,
+ 'build': '?',
+ 'src1': {'pack3': {'__init__.py': None,
+ '_build.py': None}}})
+
+ @chdir_to_tmp
+ def test_setuptools_api_2(self):
+ self._make_setuptools_api()
+ self.run(["setup.py", "build_ext", "-i"])
+ self.check_produced_files({'setup.py': None,
+ 'build': '?',
+ 'src1': {'pack3': {'__init__.py': None,
+ '_build.py': None,
+ 'mymod.SO': None}}})
diff --git a/rpython/doc/conf.py b/rpython/doc/conf.py
--- a/rpython/doc/conf.py
+++ b/rpython/doc/conf.py
@@ -66,9 +66,9 @@
# built documents.
#
# The short X.Y version.
-version = '2.5'
+version = '2.6'
# The full version, including alpha/beta/rc tags.
-release = '2.5.0'
+release = '2.6.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/rpython/jit/backend/llsupport/codemap.py b/rpython/jit/backend/llsupport/codemap.py
--- a/rpython/jit/backend/llsupport/codemap.py
+++ b/rpython/jit/backend/llsupport/codemap.py
@@ -30,6 +30,7 @@
libraries.append('Kernel32')
eci = ExternalCompilationInfo(post_include_bits=["""
+
RPY_EXTERN long pypy_jit_codemap_add(unsigned long addr,
unsigned int machine_code_size,
long *bytecode_info,
@@ -47,7 +48,8 @@
"""], separate_module_sources=[
open(os.path.join(srcdir, 'skiplist.c'), 'r').read() +
open(os.path.join(srcdir, 'codemap.c'), 'r').read()
-], include_dirs=[cdir], libraries=libraries)
+], include_dirs=[cdir], libraries=libraries,
+compile_extra=['-DPYPY_JIT_CODEMAP'])
def llexternal(name, args, res):
return rffi.llexternal(name, args, res, compilation_info=eci,
More information about the pypy-commit
mailing list