Andrew Dalke wrote: > Hi all, > > I'm working with the Akara project. It contains a web server. The server > loads extensions from a special directory (let's say "$AKARA" for now). An > extension can register handlers for URLs. An example extension might look > like: > > installs to $AKARA/spam_extension.py > (note: only .py files are supported; not even .pyc files) > ========================= > from akara.services import simple_service > > import my_spam # This is part of the distribution, and gets put in > site-packages > > @simple_service("GET", "http://vikings.protocol.id/") > def vikings(say=my_spam.DEFAULT_TEXT): > return my_spam.vikings(say) > ========================= > > > We want people to be able to distribute Akara plugins and install via > setup.py. Ideally I would like to say: > > from distutils.core import setup > from akara.distutils ... I'm not sure what here ... > > setup(name="Spam services", > package="my_spam", > akara_extensions=["spam_extension.py"] > ) > > > To clarify, the development/distribution package looks like: > $PACKAGE/setup.py > $PACKAGE/README > $PACKAGE/spam_extensions.py > $PACKAGE/my_spam/__init__.py > $PACKAGE/my_spam/dramatis_personae.py > $PACKAGE/my_spam/cafe.py > > and $PACKAGE/spam_extensions.py goes to $AKARA/spam_extensions.py while > $PACKAGE/my_spam is copied to site-packages. > > The installation does not need to byte-compile spam_extension.py. > > It should also include spam_extension.py in any distribution that it makes. > > > I looked through the documentation and searched for existing examples, but > found nothing which does this. The plugins I found used entry_points, and > that's an architecture change which I don't think is appropriate for us.
I won't comment on entry_points, as I have never used them. The way I would do it is by having akara distutils extensions, which define in particular a setup function and associated classes. Here is the code: import shutil from distutils.core import setup as _setup from distutils.core import Command from distutils import log # XXX: you will need to handle setuptools (and distribute, and....) # monkey-patching for the below commands from distutils.command.install import install as old_install from distutils.dist import Distribution as _Distribution # Where to install akara extensions AKARA_SITE = '/tmp' def setup(**kw): new_kw = kw.copy() # Handle commands overriding cmdclass = new_kw.get('cmdclass', {}) if 'install' in cmdclass: install = cmdclass['install'] else: install = old_install class my_install(install): sub_commands = install.sub_commands + [ ('install_akara_extensions', lambda x: True) ] class install_akara_extensions(Command): description = "Command to install akara extensions" user_options = [ ('akara-site=', None, 'Akara plugin directory install'), ] def initialize_options(self): self.install_dir = None self.akara_site = None self.outfiles = [] def finalize_options(self): if self.akara_site is None: self.akara_site = AKARA_SITE def run (self): dist = self.distribution for a in dist.akara_extensions: log.info("Installing akara extension %s in %s" % (a, self.akara_site)) shutil.copy(a, self.akara_site) new_cmdclass = {} new_cmdclass.update(cmdclass) new_cmdclass['install'] = my_install new_cmdclass['install_akara_extensions'] = install_akara_extensions new_kw['cmdclass'] = new_cmdclass # Handle overriden distclass if not 'distclass' in new_kw: Distribution = new_kw['distclass'] else: Distribution = _Distribution class MyDistribution(Distribution): def __init__(self, attrs=None): assert not hasattr(self, 'akara_extensions') if 'akara_extensions' in attrs: self.akara_extensions = attrs['akara_extensions'] else: self.akara_extensions = [] Distribution.__init__(self, attrs) new_kw['distclass'] = MyDistribution return _setup(**new_kw) setup(name="Spam services", packages=["my_spam"], akara_extensions=["spam_extension.py"] ) This is the minimal code to support this semi correctly. Note that many things are not handled correctly: - get_output for install_akara_extensions should be handled - most likely it will break for semi-random distutils extensions, including setuptools and distribute: you will need to detect monkey-patching to decide which Distribution and install commands to override. I have not done it because it requires the extensions to be in a separate package (to conditionally import things depending on detected monkey patching). If you think this is insane, you are not alone :) David _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig