[pypy-commit] cffi cffi-1.0: Use execfile() to load the build script from setuptools_ext, instead

arigo noreply at buildbot.pypy.org
Sun May 17 11:15:07 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r2026:f33e5caa0b88
Date: 2015-05-17 11:15 +0200
http://bitbucket.org/cffi/cffi/changeset/f33e5caa0b88/

Log:	Use execfile() to load the build script from setuptools_ext, instead
	of importing it the usual way.

diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
 
 
-* cffi_modules, now with the *path as a filename*!
-
 * also support ABI-mode in cffi_modules
diff --git a/cffi/setuptools_ext.py b/cffi/setuptools_ext.py
--- a/cffi/setuptools_ext.py
+++ b/cffi/setuptools_ext.py
@@ -9,6 +9,16 @@
     raise DistutilsSetupError(msg)
 
 
+def execfile(filename, glob):
+    # We use execfile() (here rewritten for Python 3) instead of
+    # __import__() to load the build script.  The problem with
+    # a normal import is that in some packages, the intermediate
+    # __init__.py files may already try to import the file that
+    # we are generating.
+    with open(filename) as f:
+        code = compile(f.read(), filename, 'exec')
+    exec(code, glob, glob)
+
 def add_cffi_module(dist, mod_spec):
     import os
     from cffi.api import FFI
@@ -23,14 +33,24 @@
               " not %r" % (type(mod_spec).__name__,))
     mod_spec = str(mod_spec)
     try:
-        build_mod_name, ffi_var_name = mod_spec.split(':')
+        build_file_name, ffi_var_name = mod_spec.split(':')
     except ValueError:
-        error("%r must be of the form 'build_mod_name:ffi_variable'" %
+        error("%r must be of the form 'path/build.py:ffi_variable'" %
               (mod_spec,))
-    mod = __import__(build_mod_name, None, None, [ffi_var_name])
+    if not os.path.exists(build_file_name):
+        ext = ''
+        rewritten = build_file_name.replace('.', '/') + '.py'
+        if os.path.exists(rewritten):
+            ext = ' (rewrite cffi_modules to [%r])' % (
+                rewritten + ':' + ffi_var_name,)
+        error("%r does not name an existing file%s" % (build_file_name, ext))
+
+    mod_vars = {}
+    execfile(build_file_name, mod_vars)
+
     try:
-        ffi = getattr(mod, ffi_var_name)
-    except AttributeError:
+        ffi = mod_vars[ffi_var_name]
+    except KeyError:
         error("%r: object %r not found in module" % (mod_spec,
                                                      ffi_var_name))
     if not isinstance(ffi, FFI):
@@ -40,8 +60,7 @@
                                                       type(ffi).__name__))
     if not hasattr(ffi, '_assigned_source'):
         error("%r: the set_source() method was not called" % (mod_spec,))
-    module_name = ffi._recompiler_module_name
-    source, kwds = ffi._assigned_source
+    module_name, source, source_extension, kwds = ffi._assigned_source
     if ffi._windows_unicode:
         kwds = kwds.copy()
         ffi._apply_windows_unicode(kwds)
@@ -51,7 +70,7 @@
     ext = Extension(name=module_name, sources=allsources, **kwds)
 
     def make_mod(tmpdir):
-        file_name = module_name + '.c'
+        file_name = module_name + source_extension
         log.info("generating cffi module %r" % file_name)
         mkpath(tmpdir)
         c_file = os.path.join(tmpdir, file_name)
diff --git a/demo/_curses_setup.py b/demo/_curses_setup.py
--- a/demo/_curses_setup.py
+++ b/demo/_curses_setup.py
@@ -6,7 +6,7 @@
     py_modules=["_curses"],
     setup_requires=["cffi>=1.0.dev0"],
     cffi_modules=[
-        "_curses_build:ffi",
+        "_curses_build.py:ffi",
     ],
     install_requires=["cffi>=1.0.dev0"],   # should maybe be "cffi-backend" only?
     zip_safe=False,
diff --git a/demo/bsdopendirtype_build.py b/demo/bsdopendirtype_build.py
--- a/demo/bsdopendirtype_build.py
+++ b/demo/bsdopendirtype_build.py
@@ -15,11 +15,9 @@
 """)
 
 ffi.set_source("_bsdopendirtype", """
-extern "C" {
     #include <sys/types.h>
     #include <dirent.h>
-}
-""", source_extension='.cpp')
+""")
 
 if __name__ == '__main__':
     ffi.compile()
diff --git a/demo/bsdopendirtype_setup.py b/demo/bsdopendirtype_setup.py
--- a/demo/bsdopendirtype_setup.py
+++ b/demo/bsdopendirtype_setup.py
@@ -6,7 +6,7 @@
     py_modules=["bsdopendirtype"],
     setup_requires=["cffi>=1.0.dev0"],
     cffi_modules=[
-        "bsdopendirtype_build:ffi",
+        "bsdopendirtype_build.py:ffi",
     ],
     install_requires=["cffi>=1.0.dev0"],   # should maybe be "cffi-backend" only?
     zip_safe=False,


More information about the pypy-commit mailing list