[libpeas] Compile internal Python source during build



commit 917dbb5a0e8c2d787daeec5c9e667fc794791c44
Author: Garrett Regier <garrettregier gmail com>
Date:   Sun Jan 4 17:21:04 2015 -0800

    Compile internal Python source during build
    
    Otherwise syntax errors aren't noticed until the loader
    is initialized at runtime.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742348

 configure.ac                               |    4 ++
 loaders/python/Makefile.am                 |   10 ++++-
 loaders/python/peas-plugin-loader-python.c |    7 +++
 loaders/python/peas-python-compile.py      |   59 ++++++++++++++++++++++++++++
 loaders/python3/Makefile.am                |   11 ++++-
 5 files changed, 88 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 45293f6..f55bdbc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -393,10 +393,12 @@ else
             if test -n "${PYTHON2_CONFIG}"; then
                 PKG_CHECK_MODULES(PYGOBJECT, pygobject-3.0 >= $PYGOBJECT_REQUIRED, [
                     found_python2=yes
+                    PYTHON2_BIN="$PYTHON2"
                     PYTHON2_CFLAGS=`${PYTHON2_CONFIG} --includes`
                     PYTHON2_LIBS=`${PYTHON2_CONFIG} --libs`
                     PYTHON2_LDFLAGS=`${PYTHON2_CONFIG} --ldflags`
                     PYTHON2_PYEXECDIR=`$PYTHON2 -c "from distutils import sysconfig; 
print(sysconfig.get_python_lib(1, 0, prefix='\\$' '{exec_prefix}'))"`
+                    AC_SUBST(PYTHON2_BIN)
                     AC_SUBST(PYTHON2_CFLAGS)
                     AC_SUBST(PYTHON2_LIBS)
                     AC_SUBST(PYTHON2_LDFLAGS)
@@ -437,10 +439,12 @@ else
         if test -n "${PYTHON3_CONFIG}"; then
             PKG_CHECK_MODULES(PYGOBJECT, pygobject-3.0 >= $PYGOBJECT_REQUIRED, [
                 found_python3=yes
+                PYTHON3_BIN="$PYTHON"
                 PYTHON3_CFLAGS=`${PYTHON3_CONFIG} --includes`
                 PYTHON3_LIBS=`${PYTHON3_CONFIG} --libs`
                 PYTHON3_LDFLAGS=`${PYTHON3_CONFIG} --ldflags`
                 PYTHON3_PYEXECDIR="${pyexecdir}"
+                AC_SUBST(PYTHON3_BIN)
                 AC_SUBST(PYTHON3_CFLAGS)
                 AC_SUBST(PYTHON3_LIBS)
                 AC_SUBST(PYTHON3_LDFLAGS)
diff --git a/loaders/python/Makefile.am b/loaders/python/Makefile.am
index 9cbe765..843ea2b 100644
--- a/loaders/python/Makefile.am
+++ b/loaders/python/Makefile.am
@@ -31,15 +31,23 @@ libpythonloader_la_LIBADD = \
        $(PYGOBJECT_LIBS)                       \
        $(PYTHON2_LIBS)
 
+peas-plugin-loader-python-internal.pyc: peas-plugin-loader-python-internal.py
+       $(AM_V_GEN) $(PYTHON2_BIN) $(srcdir)/peas-python-compile.py $< $@
+
+all-local: peas-plugin-loader-python-internal.pyc
+
 loader_resources_deps = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies 
$(srcdir)/peas-plugin-loader-python.gresource.xml)
 peas-plugin-loader-python-resources.c: $(srcdir)/peas-plugin-loader-python.gresource.xml 
$(loader_resources_deps)
        $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --internal --target=$@ --sourcedir=$(srcdir) --generate-source 
$(srcdir)/peas-plugin-loader-python.gresource.xml
 
 EXTRA_DIST = \
+       peas-python-compile.py                          \
        peas-plugin-loader-python.gresource.xml         \
        $(loader_resources_deps)
 
-CLEANFILES = peas-plugin-loader-python-resources.c
+CLEANFILES = \
+       peas-plugin-loader-python-internal.pyc          \
+       peas-plugin-loader-python-resources.c
 
 gcov_sources = $(libpythonloader_la_SOURCES)
 include $(top_srcdir)/Makefile.gcov
diff --git a/loaders/python/peas-plugin-loader-python.c b/loaders/python/peas-plugin-loader-python.c
index 4731ad5..e4f4340 100644
--- a/loaders/python/peas-plugin-loader-python.c
+++ b/loaders/python/peas-plugin-loader-python.c
@@ -581,6 +581,13 @@ peas_plugin_loader_python_initialize (PeasPluginLoader *loader)
   if (builtins_module == NULL)
     goto python_init_error;
 
+  /* We don't use the byte-compiled Python source
+   * because glib-compile-resources cannot output
+   * depends for generated files.
+   *
+   * https://bugzilla.gnome.org/show_bug.cgi?id=673101
+   */
+
   internal_python = g_resources_lookup_data ("/org/gnome/libpeas/loaders/"
 #if PY_VERSION_HEX < 0x03000000
                                              "python/"
diff --git a/loaders/python/peas-python-compile.py b/loaders/python/peas-python-compile.py
new file mode 100644
index 0000000..cdc2b0a
--- /dev/null
+++ b/loaders/python/peas-python-compile.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+#  Copyright (C) 2015 - Garrett Regier
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Library General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+import marshal
+import sys
+import traceback
+
+
+def compile_file(filename, output):
+    """Byte-compiles a Python source file to Python bytecode.
+
+       Unlike py_compile the output is not prefixed
+       by a magic value, mtime or size.
+    """
+    # Open with universal newlines
+    with open(filename, 'U') as f:
+        code = f.read() + '\n'
+
+    try:
+        code_object = compile(code, filename, 'exec')
+
+    except (SyntaxError, TypeError) as error:
+        tb = traceback.format_exc(0).rstrip('\n')
+        raise Exception('Failed to compile "{0}":\n{1}'.format(filename, tb))
+
+    with open(output, 'wb') as f:
+        marshal.dump(code_object, f)
+        f.flush()
+
+
+def main(args):
+    try:
+        for i in range(0, len(args), 2):
+            compile_file(args[i], args[i + 1])
+
+    except Exception as error:
+        sys.exit('Error: {0!s}'.format(error))
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
+
+# ex:ts=4:et:
diff --git a/loaders/python3/Makefile.am b/loaders/python3/Makefile.am
index d2b75c9..9c8756e 100644
--- a/loaders/python3/Makefile.am
+++ b/loaders/python3/Makefile.am
@@ -31,15 +31,22 @@ libpython3loader_la_LIBADD = \
        $(PYGOBJECT_LIBS)                       \
        $(PYTHON3_LIBS)
 
+peas-plugin-loader-python3-internal.pyc: $(srcdir)/../python/peas-plugin-loader-python-internal.py
+       $(AM_V_GEN) $(PYTHON3_BIN) $(srcdir)/../python/peas-python-compile.py $< $@
+
+all-local: peas-plugin-loader-python3-internal.pyc
+
 loader_resources_deps = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies 
$(srcdir)/peas-plugin-loader-python3.gresource.xml)
 peas-plugin-loader-python3-resources.c: $(srcdir)/peas-plugin-loader-python3.gresource.xml 
$(loader_resources_deps)
        $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --internal --target=$@ --sourcedir=$(srcdir) --generate-source 
$(srcdir)/peas-plugin-loader-python3.gresource.xml
 
 EXTRA_DIST = \
-       peas-plugin-loader-python3.gresource.xml                \
+       peas-plugin-loader-python3.gresource.xml        \
        $(loader_resources_deps)
 
-CLEANFILES = peas-plugin-loader-python3-resources.c
+CLEANFILES = \
+       peas-plugin-loader-python3-internal.pyc         \
+       peas-plugin-loader-python3-resources.c
 
 gcov_sources = $(libpython3loader_la_SOURCES)
 include $(top_srcdir)/Makefile.gcov


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]