summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCedric Gustin <cedric.gustin@gmail.com>2006-09-21 07:13:40 +0000
committerCedric Gustin <gustin@src.gnome.org>2006-09-21 07:13:40 +0000
commit16d397d8f104b04c4de5f97957b5ae5cc6d27b74 (patch)
tree7c610c061e044ac80689d4d2bf3e4adad2640853
parent7e823bfb034b82377d092e954d9f73c48af5795f (diff)
downloadpygobject-16d397d8f104b04c4de5f97957b5ae5cc6d27b74.tar.gz
pygobject-16d397d8f104b04c4de5f97957b5ae5cc6d27b74.tar.xz
pygobject-16d397d8f104b04c4de5f97957b5ae5cc6d27b74.zip
Catch ImportError exception when codegen is not available: disable
2006-09-21 Cedric Gustin <cedric.gustin@gmail.com> * dsextras.py: Catch ImportError exception when codegen is not available: disable Template and TemplateExtension, redirect the user to the pygtk installer and raise a NameError exception. check_date has also been rewritten and now uses distutils.dep_util.newer_group(). defs files can also be built using createdefs by passing tuples as keyword argument to Template (see for example the gdk and gtk templates in setup.py). * setup.py: Changed the way the VERSION macro is defined on win32. Also install the html reference documentation, the xsl files and fixxref. * pygobject_postinstall.py: Set the value of DATADIR in fixxref.py. Add functions to install shortcuts in the Start menu to the reference manual (currently disabled: see bug #353849).
-rw-r--r--ChangeLog16
-rw-r--r--dsextras.py131
-rw-r--r--pygobject_postinstall.py89
-rwxr-xr-xsetup.py14
4 files changed, 177 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index d817805..b72bba2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-09-21 Cedric Gustin <cedric.gustin@gmail.com>
+
+ * dsextras.py: Catch ImportError exception when codegen is not
+ available: disable Template and TemplateExtension, redirect the
+ user to the pygtk installer and raise a NameError
+ exception. check_date has also been rewritten and now uses
+ distutils.dep_util.newer_group(). defs files can also be built
+ using createdefs by passing tuples as keyword argument to Template
+ (see for example the gdk and gtk templates in setup.py).
+ * setup.py: Changed the way the VERSION macro is defined on win32.
+ Also install the html reference documentation, the xsl files and
+ fixxref.
+ * pygobject_postinstall.py: Set the value of DATADIR in
+ fixxref.py. Add functions to install shortcuts in the Start menu
+ to the reference manual (currently disabled: see bug #353849).
+
2006-09-16 Gustavo J. A. M. Carneiro <gjc@gnome.org>
* tests/test_signal.py (TestEmissionHook.testCallbackReturnFalse)
diff --git a/dsextras.py b/dsextras.py
index 006e5d6..b8b642b 100644
--- a/dsextras.py
+++ b/dsextras.py
@@ -1,14 +1,13 @@
#
-# dsextras.py - Extra classes and utilities
-#
-# TODO:
-# Make it possible to import codegen from another dir
-#
+# dsextras.py - Extra classes and utilities for distutils, adding
+# pkg-config support
+
from distutils.command.build_ext import build_ext
from distutils.command.install_lib import install_lib
from distutils.command.install_data import install_data
from distutils.extension import Extension
+import distutils.dep_util
import fnmatch
import os
import re
@@ -80,10 +79,11 @@ def list_files(dir):
retval.append(os.path.join(dir, file))
return retval
-def pkgc_version_check(name, longname, req_version):
+def pkgc_version_check(name, req_version):
+ """Check the existence and version number of a package:
+ returns 0 if not installed or too old, 1 otherwise."""
is_installed = not os.system('pkg-config --exists %s' % name)
if not is_installed:
- print "Could not find %s" % longname
return 0
orig_version = getoutput('pkg-config --modversion %s' % name)
@@ -92,12 +92,8 @@ def pkgc_version_check(name, longname, req_version):
if version >= pkc_version:
return 1
- else:
- print "Warning: Too old version of %s" % longname
- print " Need %s, but %s is installed" % \
- (pkc_version, orig_version)
- self.can_build_ok = 0
- return 0
+
+ return 0
class BuildExt(build_ext):
def init_extra_compile_args(self):
@@ -213,10 +209,10 @@ class InstallData(install_data):
return output
def get_outputs(self):
- return install_lib.get_outputs(self) + self.local_outputs
+ return install_data.get_outputs(self) + self.local_outputs
def get_inputs(self):
- return install_lib.get_inputs(self) + self.local_inputs
+ return install_data.get_inputs(self) + self.local_inputs
class PkgConfigExtension(Extension):
# Name of pygobject package extension depends on, can be None
@@ -301,44 +297,81 @@ class PkgConfigExtension(Extension):
def generate(self):
pass
-class Template:
+# The Template and TemplateExtension classes require codegen which is
+# currently part of the pygtk distribution. While codegen might ultimately
+# be moved to pygobject, it was decided (bug #353849) to keep the Template
+# and TemplateExtension code in dsextras. In the meantime, we check for the
+# availability of codegen and redirect the user to the pygtk installer if
+# he/she wants to get access to Template and TemplateExtension.
+
+template_classes_enabled=True
+codegen_error_message="""
+***************************************************************************
+Codegen could not be found on your system and is required by the
+dsextras.Template and dsextras.TemplateExtension classes. codegen is part
+of PyGTK. To use either Template or TemplateExtension, you should also
+install PyGTK.
+***************************************************************************
+"""
+try:
+ from codegen.override import Overrides
+ from codegen.defsparser import DefsParser
+ from codegen.codegen import register_types, SourceWriter, \
+ FileOutput
+ import codegen.createdefs
+except ImportError, e:
+ template_classes_enabled=False
+
+class Template(object):
+ def __new__(cls,*args, **kwds):
+ if not template_classes_enabled:
+ raise NameError("'%s' is not defined\n" % cls.__name__
+ + codegen_error_message)
+ return object.__new__(cls,*args, **kwds)
+
def __init__(self, override, output, defs, prefix,
register=[], load_types=None):
+
self.override = override
- self.defs = defs
- self.register = register
self.output = output
self.prefix = prefix
self.load_types = load_types
- def check_dates(self):
- if not os.path.exists(self.output):
- return 0
+ self.built_defs=[]
+ if isinstance(defs,tuple):
+ self.defs=defs[0]
+ self.built_defs.append(defs)
+ else:
+ self.defs=defs
- files = self.register[:]
+ self.register=[]
+ for r in register:
+ if isinstance(r,tuple):
+ self.register.append(r[0])
+ self.built_defs.append(r)
+ else:
+ self.register.append(r)
+
+ def check_dates(self):
+ # Return True if files are up-to-date
+ files=self.register[:]
files.append(self.override)
-# files.append('setup.py')
files.append(self.defs)
- newest = 0
- for file in files:
- test = os.stat(file)[8]
- if test > newest:
- newest = test
+ return not distutils.dep_util.newer_group(files,self.output)
- if newest < os.stat(self.output)[8]:
- return 1
- return 0
+ def generate_defs(self):
+ for (target,sources) in self.built_defs:
+ if distutils.dep_util.newer_group(sources,target):
+ # createdefs is mostly called from the CLI !
+ args=['dummy',target]+sources
+ codegen.createdefs.main(args)
- def generate(self):
- # We must insert it first, otherwise python will try '.' first,
- # in which it exist a "bogus" codegen (the third import line
- # here will fail)
- sys.path.insert(0, 'codegen')
- from override import Overrides
- from defsparser import DefsParser
- from codegen import register_types, write_source, FileOutput
+ def generate(self):
+ # Generate defs files if necessary
+ self.generate_defs()
+ # ... then check the file timestamps
if self.check_dates():
return
@@ -356,17 +389,25 @@ class Template:
register_types(dp)
fd = open(self.output, 'w')
- write_source(dp,
- Overrides(self.override),
- self.prefix,
- FileOutput(fd, self.output))
+ sw = SourceWriter(dp,Overrides(self.override),
+ self.prefix,FileOutput(fd,self.output))
+ sw.write()
fd.close()
class TemplateExtension(PkgConfigExtension):
+ def __new__(cls,*args, **kwds):
+ if not template_classes_enabled:
+ raise NameError("'%s' is not defined\n" % cls.__name__
+ + codegen_error_message)
+ return PkgConfigExtension.__new__(cls,*args, **kwds)
+
def __init__(self, **kwargs):
name = kwargs['name']
defs = kwargs['defs']
- output = defs[:-5] + '.c'
+ if isinstance(defs,tuple):
+ output = defs[0][:-5] + '.c'
+ else:
+ output = defs[:-5] + '.c'
override = kwargs['override']
load_types = kwargs.get('load_types')
self.templates = []
@@ -385,3 +426,5 @@ class TemplateExtension(PkgConfigExtension):
def generate(self):
map(lambda x: x.generate(), self.templates)
+
+
diff --git a/pygobject_postinstall.py b/pygobject_postinstall.py
index 0175d00..8ddaa60 100644
--- a/pygobject_postinstall.py
+++ b/pygobject_postinstall.py
@@ -1,26 +1,63 @@
-
-"""pygtk is now installed on your machine.
-
-Local configuration files were successfully updated."""
-
-import os, re, sys
-
-prefix_pattern=re.compile("^prefix=.*")
-
-def replace_prefix(s):
- if prefix_pattern.match(s):
- s='prefix='+sys.prefix.replace("\\","\\\\")+'\n'
- return s
-
-
-if len(sys.argv) == 2 and sys.argv[1] == "-install":
-
- filenames=['lib/pkgconfig/pygobject-2.0.pc']
- for filename in filenames:
- pkgconfig_file = os.path.normpath(
- os.path.join(sys.prefix,filename))
-
- lines=open(pkgconfig_file).readlines()
- open(pkgconfig_file, 'w').writelines(map(replace_prefix,lines))
-
- print __doc__
+
+"""pygobject is now installed on your machine.
+
+Local configuration files were successfully updated."""
+
+import os, re, sys
+
+prefix_pattern=re.compile("^prefix=.*")
+
+
+def replace_prefix(s):
+ if prefix_pattern.match(s):
+ s='prefix='+sys.prefix.replace("\\","/")+'\n'
+ s=s.replace("@DATADIR@",
+ os.path.join(sys.prefix,'share').replace("\\","/"))
+
+ return s
+
+# TODO : Check that shortcuts are created system-wide when the user
+# has admin rights (hint: see pywin32 postinstall)
+def create_shortcuts():
+ progs_folder= get_special_folder_path("CSIDL_COMMON_PROGRAMS")
+ site_packages_dir = os.path.join(sys.prefix , 'lib','site-packages')
+
+ pygtk_shortcuts = os.path.join(progs_folder, 'PyGTK')
+ if not os.path.isdir(pygtk_shortcuts):
+ os.mkdir(pygtk_shortcuts)
+
+ pygobject_doc_link=os.path.join(pygtk_shortcuts,
+ 'PyGObject Documentation.lnk')
+ if os.path.isfile(pygobject_doc_link):
+ os.remove(pygobject_doc_link)
+
+ create_shortcut(os.path.join(sys.prefix,'share','gtk-doc','html',
+ 'pygobject','index.html'),
+ 'PyGObject Documentation', pygobject_doc_link)
+
+def remove_shortcuts():
+ pygtk_shortcuts = os.path.join(
+ get_special_folder_path('CSIDL_COMMON_PROGRAMS'), 'PyGTK')
+ os.remove(os.path.join(pygtk_shortcuts,'PyGObject Documentation.lnk'))
+ try:
+ os.rmdir(pygtk_shortcuts)
+ except OSError, e:
+ # Directory is not empty, so leave it like that !
+ pass
+
+if len(sys.argv) == 2:
+ if sys.argv[1] == "-install":
+ filenames=['lib/pkgconfig/pygobject-2.0.pc',
+ 'share/pygobject/xsl/fixxref.py']
+ for filename in filenames:
+ pkgconfig_file = os.path.normpath(
+ os.path.join(sys.prefix,filename))
+
+ lines=open(pkgconfig_file).readlines()
+ open(pkgconfig_file, 'w').writelines(map(replace_prefix,lines))
+ # TODO: Add an installer option for shortcut creation
+ # create_shortcuts()
+ print __doc__
+ elif sys.argv[1] == "-remove":
+ pass
+ # remove_shortcuts()
diff --git a/setup.py b/setup.py
index 3cced9f..31cad8e 100755
--- a/setup.py
+++ b/setup.py
@@ -6,6 +6,7 @@
from distutils.command.build import build
from distutils.core import setup
+import glob
import os
import sys
@@ -48,12 +49,14 @@ GLOBAL_MACROS += [('PYGOBJECT_MAJOR_VERSION', MAJOR_VERSION),
('PYGOBJECT_MINOR_VERSION', MINOR_VERSION),
('PYGOBJECT_MICRO_VERSION', MICRO_VERSION)]
-if sys.platform == 'win32':
- GLOBAL_MACROS.append(('VERSION', '\\\"%s\\\"' % VERSION))
+if sys.platform == 'win33':
+ GLOBAL_MACROS.append(('VERSION', '"""%s"""' % VERSION))
else:
GLOBAL_MACROS.append(('VERSION', '"%s"' % VERSION))
INCLUDE_DIR = os.path.join('include', 'pygtk-%s' % PYGOBJECT_SUFFIX)
+XSL_DIR = os.path.join('share', 'pygobject','xsl')
+HTML_DIR = os.path.join('share', 'gtk-doc', 'html', 'pygobject')
class PyGObjectInstallLib(InstallLib):
def run(self):
@@ -98,6 +101,8 @@ class PyGObjectInstallData(InstallData):
self.install_template('pygobject-2.0.pc.in',
os.path.join(self.install_dir,
'lib', 'pkgconfig'))
+ self.install_template('docs/xsl/fixxref.py.in',
+ os.path.join(self.install_dir, XSL_DIR))
class PyGObjectBuild(build):
enable_threading = 1
@@ -128,7 +133,6 @@ data_files = []
ext_modules = []
py_modules = []
py_modules.append('dsextras')
-py_modules.append('gobject.option')
if not have_pkgconfig():
print "Error, could not find pkg-config"
@@ -136,7 +140,11 @@ if not have_pkgconfig():
if gobject.can_build():
ext_modules.append(gobject)
+ py_modules.append('gobject.option')
data_files.append((INCLUDE_DIR, ('gobject/pygobject.h',)))
+ data_files.append((HTML_DIR, glob.glob('docs/html/*.html')))
+ data_files.append((HTML_DIR, ['docs/style.css']))
+ data_files.append((XSL_DIR, glob.glob('docs/xsl/*.xsl')))
else:
print
print 'ERROR: Nothing to do, gobject could not be found and is essential.'