View of /PEAK/setup.py
Parent Directory
| Revision Log
Revision:
766 -
(
download)
(
as text)
Fri Nov 29 22:20:23 2002 UTC (21 years, 4 months ago) by
pje
File size: 4971 byte(s)
Refactored to allow "lazy" metadata computation, using bindings.
This means that you can use attribute bindings in metaclasses to assemble
metadata registries, such as those needed for XMI.
Unfortunately, for this to work on types, I had to change the fundamental
implementation of attribute bindings to a new implementation in Pyrex/C.
The problem is that only *data* descriptors from a metaclass are invoked
if there is an attribute value available in the type's dictionary or the
dictionary of one of its base types. This means that trying to have
'Once' bindings that attach to classes via their metaclass, is inherently
unstable unless you make use of the bindings in strict reverse __mro__
order! This problem has actually existed ever since I added the ability
to use bindings in metaclasses, but because of the way things were being
used, it "just happened" to look like it was working.
So I had to make 'Once' a data descriptor; unfortunately this means that
it has to check whether the value appears in the object's dictionary
*every* time the attribute is accessed. That's still doable from Python,
but the bigger problem is that type dictionaries aren't accessible from
pure Python code, and the only way to implement the __set__ function on
a 'Once' descriptor is by writing to the dictionary. So I wrote a Pyrex
extension type to support getting at the object's true dictionary, and
to implement a (relatively) fast __get__ method. The result seems to
perform about as well as the old version, although I'm tempted to redo
some of it in pure C to get rid of a lot of overhead that would be
avoidable if Pyrex properly supported the '__get__' signature for
extension types.
Up next: standardizing the metaclass naming convention, documenting all this
stuff, then maybe on to XMI writing...
#!/usr/bin/env python
"""Distutils setup file"""
from distutils.core import setup, Command, Extension
from distutils.command.install_data import install_data
from distutils.command.sdist import sdist as old_sdist
from distutils.command.build_ext import build_ext as old_build_ext
import sys
try:
from Pyrex.Distutils.build_ext import build_ext
EXT = '.pyx'
except ImportError:
build_ext = old_build_ext
EXT = '.c'
class install_data(install_data):
"""Variant of 'install_data' that installs data to module directories"""
def finalize_options (self):
self.set_undefined_options('install',
('install_lib', 'install_dir'),
('root', 'root'),
('force', 'force'),
)
class sdist(old_sdist):
"""Variant of 'sdist' that (re)builds the documentation first"""
def run(self):
# Build docs before source distribution
self.run_command('happy')
# Run the standard sdist command
old_sdist.run(self)
class test(Command):
"""Command to run unit tests after installation"""
description = "Run unit tests after installation"
user_options = [('test-module=','m','Test module (default=peak.tests)'),]
def initialize_options(self):
self.test_module = None
def finalize_options(self):
if self.test_module is None:
self.test_module = 'peak.api.tests'
self.test_args = [self.test_module+'.test_suite']
if self.verbose:
self.test_args.insert(0,'--verbose')
def run(self):
# Install before testing
self.run_command('install')
if not self.dry_run:
from unittest import main
main(None, None, sys.argv[:1]+self.test_args)
class happy(Command):
"""Command to generate documentation using HappyDoc
I should probably make this more general, and contribute it to either
HappyDoc or the distutils, but this does the trick for PEAK for now...
"""
description = "Generate docs using happydoc"
user_options = []
def initialize_options(self):
self.happy_options = None
self.doc_output_path = None
def finalize_options(self):
if self.doc_output_path is None:
self.doc_output_path = 'docs/html/reference'
if self.happy_options is None:
self.happy_options = [
'-t', 'PEAK Reference', '-d', self.doc_output_path,
'-i', 'examples', '-i', 'old', '-i', 'tests',
'-i', 'metamodels', '-i', 'Interface', '-i', 'Persistence',
'-i', 'kjbuckets', '.'
]
if not self.verbose: self.happy_options.insert(0,'-q')
def run(self):
from distutils.dir_util import remove_tree, mkpath
from happydoclib import HappyDoc
mkpath(self.doc_output_path, 0755, self.verbose, self.dry_run)
remove_tree(self.doc_output_path, self.verbose, self.dry_run)
if not self.dry_run:
HappyDoc(self.happy_options).run()
setup(
name="PEAK",
version="0.5a0",
description="The Python Enterprise Application Kit",
author="Phillip J. Eby",
author_email="transwarp@eby-sarna.com",
url="http://www.telecommunity.com/PEAK/",
license="PSF or ZPL",
platforms=['UNIX','Windows'],
packages=[
'peak', 'peak.api', 'peak.binding', 'peak.model', 'peak.metamodels',
'peak.metamodels.mof', 'peak.metamodels.uml',
'peak.naming', 'peak.naming.factories', 'peak.util', 'peak.running',
'peak.config', 'peak.storage',
'peak.binding.tests', 'peak.config.tests', 'peak.storage.tests',
'peak.metamodels.tests', 'peak.util.tests', 'peak.naming.tests',
'peak.model.tests', 'peak.tests', 'peak.running.tests',
'Interface', 'Interface.tests',
'Interface.Common', 'Interface.Common.tests',
'Interface.Registry', 'Interface.Registry.tests',
'Persistence',
],
package_dir = {'':'src'},
ext_modules = [
Extension("kjbuckets", ["src/kjbuckets/kjbucketsmodule.c"]),
Extension("Persistence.cPersistence",
["src/Persistence/cPersistence.c"]
),
Extension("peak.binding.data_desc", ["src/peak/binding/data_desc" + EXT]),
Extension("peak.util.buffer_gap", ["src/peak/util/buffer_gap" + EXT]),
Extension("peak.util._Code", ["src/peak/util/_Code" + EXT]),
],
cmdclass = {
'install_data': install_data, 'sdist': sdist, 'happy': happy,
'test': test, 'sdist_nodoc': old_sdist, 'build_ext': build_ext,
},
data_files = [
('peak', ['src/peak/peak.ini']),
('peak/running/tests', ['src/peak/running/tests/test_cluster.txt']),
('peak/metamodels/tests', ['src/peak/metamodels/tests/MetaMeta.xml']),
],
)