You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(24) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
(1) |
Jun
(4) |
Jul
|
Aug
|
Sep
(1) |
Oct
(3) |
Nov
(3) |
Dec
|
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
(1) |
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
|
2010 |
Jan
|
Feb
|
Mar
(8) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Mike C. F. <mcf...@us...> - 2004-10-18 04:09:43
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21885 Modified Files: dispatcher.py Log Message: Fix memory leaks stemming from the registration and cleanup of receivers which are deleted. Index: dispatcher.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/dispatcher.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dispatcher.py 18 Feb 2004 00:29:46 -0000 1.6 --- dispatcher.py 18 Oct 2004 04:09:32 -0000 1.7 *************** *** 138,162 **** 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) ! receiverID = id( receiver ) ! if weak: receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) senderkey = id(sender) - signals = {} if connections.has_key(senderkey): signals = connections[senderkey] else: ! connections[senderkey] = signals ! # Keep track of senders for cleanup. ! # Is Anonymous something we want to clean up? ! if sender not in (None, Anonymous, Any): ! def remove(object, senderkey=senderkey): ! _removeSender(senderkey=senderkey) ! # Skip objects that can not be weakly referenced, which means ! # they won't be automatically cleaned up, but that's too bad. ! try: ! weakSender = weakref.ref(sender, remove) ! senders[senderkey] = weakSender ! sendersBack.setdefault(receiverID,[]).append(senderkey) ! except: ! pass receivers = [] if signals.has_key(signal): --- 138,168 ---- 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) ! if weak: ! receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) senderkey = id(sender) if connections.has_key(senderkey): signals = connections[senderkey] else: ! connections[senderkey] = signals = {} ! # Keep track of senders for cleanup. ! # Is Anonymous something we want to clean up? ! if sender not in (None, Anonymous, Any): ! def remove(object, senderkey=senderkey): ! _removeSender(senderkey=senderkey) ! # Skip objects that can not be weakly referenced, which means ! # they won't be automatically cleaned up, but that's too bad. ! try: ! weakSender = weakref.ref(sender, remove) ! senders[senderkey] = weakSender ! except: ! pass ! try: ! receiverID = id(receiver) ! current = sendersBack.get( receiverID ) ! if current is None: ! sendersBack[ receiverID ] = current = [] ! current.append(senderkey) ! except: ! pass receivers = [] if signals.has_key(signal): *************** *** 164,169 **** else: signals[signal] = receivers ! try: receivers.remove(receiver) ! except ValueError: pass receivers.append(receiver) --- 170,177 ---- else: signals[signal] = receivers ! try: ! receivers.remove(receiver) ! except ValueError: ! pass receivers.append(receiver) *************** *** 362,366 **** for senderkey in sendersBack.get(backKey,()): try: ! for signal in connections[senderkey].keys(): try: receivers = connections[senderkey][signal] --- 370,378 ---- for senderkey in sendersBack.get(backKey,()): try: ! signals = connections[senderkey].keys() ! except KeyError,err: ! pass ! else: ! for signal in signals: try: receivers = connections[senderkey][signal] *************** *** 368,376 **** pass else: ! try: receivers.remove(receiver) ! except: pass _cleanupConnections(senderkey, signal) ! except KeyError: ! pass def _cleanupConnections(senderkey, signal): --- 380,392 ---- pass else: ! try: ! receivers.remove( receiver ) ! except Exception, err: ! pass _cleanupConnections(senderkey, signal) ! try: ! del sendersBack[ backKey ] ! except KeyError: ! pass def _cleanupConnections(senderkey, signal): *************** *** 392,396 **** # No more signal connections. Therefore, remove the sender. _removeSender(senderkey) ! def _removeSender(senderkey): """Remove senderkey from connections.""" --- 408,412 ---- # No more signal connections. Therefore, remove the sender. _removeSender(senderkey) ! def _removeSender(senderkey): """Remove senderkey from connections.""" *************** *** 404,406 **** except: pass - \ No newline at end of file --- 420,421 ---- |
From: Mike C. F. <mcf...@us...> - 2004-09-22 16:17:37
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5227 Modified Files: pydispatcher-1.0.0.ebuild Log Message: Switch to sourceforge source URI Index: pydispatcher-1.0.0.ebuild =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/pydispatcher-1.0.0.ebuild,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pydispatcher-1.0.0.ebuild 17 Jun 2004 06:00:48 -0000 1.1 --- pydispatcher-1.0.0.ebuild 22 Sep 2004 16:17:13 -0000 1.2 *************** *** 18,24 **** DESCRIPTION="Multi-producer-multi-consumer signal dispatching mechanism for Python" HOMEPAGE="http://${PN}.sourceforge.net/" ! #SRC_URI="mirror://sourceforge/${PN}/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" # This is only temporary during my local testing phase, the sourceforge project will be the final location ! SRC_URI="http://members.rogers.com/mcfletch/programming/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" LICENSE="BSD" --- 18,24 ---- DESCRIPTION="Multi-producer-multi-consumer signal dispatching mechanism for Python" HOMEPAGE="http://${PN}.sourceforge.net/" ! SRC_URI="mirror://sourceforge/${PN}/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" # This is only temporary during my local testing phase, the sourceforge project will be the final location ! #SRC_URI="http://members.rogers.com/mcfletch/programming/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" LICENSE="BSD" |
From: Mike C. F. <mcf...@us...> - 2004-06-21 05:19:49
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31369 Modified Files: MANIFEST.in Log Message: Working around what appears to be platform-specificity in the manifest.in file. As seen here produces the 1.0.0 release including the reference documentation when run on a Win32 system. Should figure out why the results are so different on the two platforms some day. Index: MANIFEST.in =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/MANIFEST.in,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MANIFEST.in 17 Jun 2004 05:39:03 -0000 1.3 --- MANIFEST.in 21 Jun 2004 05:19:39 -0000 1.4 *************** *** 1,11 **** include MANIFEST.in include license.txt ! include * ! include docs/* ! include docs/images/* ! include docs/style/* ! include docs/pydoc/* ! include tests/* ! include examples/* global-exclude *.bat --- 1,12 ---- include MANIFEST.in include license.txt ! include *.py ! include docs *.html ! include docs/images *.png ! include docs/style *.css ! include docs/pydoc *.html *.py ! include examples *.py global-exclude *.bat + global-exclude ./CVS + global-exclude .cvsignore |
From: Mike C. F. <mcf...@us...> - 2004-06-17 06:00:58
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17222 Added Files: pydispatcher-1.0.0.ebuild Log Message: Gentoo Linux ebuild for PyDispatcher. At the moment points to a 1.0.0.tar.gz on my personal site, will have to point to sourceforge once we agree that we're at 1.0.0 final and release there. --- NEW FILE: pydispatcher-1.0.0.ebuild --- # Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors # Distributed under the terms of the BSD License # $Header: /cvsroot/pydispatcher/dispatch/pydispatcher-1.0.0.ebuild,v 1.1 2004/06/17 06:00:48 mcfletch Exp $ # This is a pretty trivial ebuild, as the python distutils support takes care of # just about everything for us. Our only real problem is that the project name # as far as distutils is concerned is PyDispatcher rather than pydispatcher. # We get around that by defining DISTUTILS_NAME as the capitalised name, # and then provide a similar customisation point DISTUTILS_VERSION which # lets us define e.g. 1.0.0a1 (which is how the package is normally numbered) # when an alpha/beta/etc version comes out with only minimal changes to this # file. inherit distutils DISTUTILS_NAME="PyDispatcher" DISTUTILS_VERSION="${PV}" # change when version has an a1 or similar extension DESCRIPTION="Multi-producer-multi-consumer signal dispatching mechanism for Python" HOMEPAGE="http://${PN}.sourceforge.net/" #SRC_URI="mirror://sourceforge/${PN}/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" # This is only temporary during my local testing phase, the sourceforge project will be the final location SRC_URI="http://members.rogers.com/mcfletch/programming/${DISTUTILS_NAME}-${DISTUTILS_VERSION}.tar.gz" LICENSE="BSD" SLOT="0" # should only be the one version installed # testing under Gentoo, though the package should be stable KEYWORDS="~x86" # should work on all python-support (i.e. Gentoo) architectures IUSE="" DEPEND="virtual/python" S="${WORKDIR}/${DISTUTILS_NAME}-${DISTUTILS_VERSION}" src_install() { distutils_src_install } |
From: Mike C. F. <mcf...@us...> - 2004-06-17 05:39:11
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31257 Modified Files: MANIFEST.in Log Message: Yet more fixes to the manifest to get the source distribution to include examples (and the core files). Index: MANIFEST.in =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/MANIFEST.in,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MANIFEST.in 17 Jun 2004 05:03:48 -0000 1.2 --- MANIFEST.in 17 Jun 2004 05:39:03 -0000 1.3 *************** *** 1,4 **** --- 1,5 ---- include MANIFEST.in include license.txt + include * include docs/* include docs/images/* *************** *** 6,9 **** --- 7,11 ---- include docs/pydoc/* include tests/* + include examples/* global-exclude *.bat |
From: Mike C. F. <mcf...@us...> - 2004-06-17 05:03:57
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1210 Modified Files: MANIFEST.in Log Message: Fix manifest to use specifications that actually *work* with distutils in order to get all the support files in the distribution. Index: MANIFEST.in =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/MANIFEST.in,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MANIFEST.in 6 Jul 2003 21:22:52 -0000 1.1 --- MANIFEST.in 17 Jun 2004 05:03:48 -0000 1.2 *************** *** 1,14 **** include MANIFEST.in include license.txt ! include *.py ! include docs ! include docs/style ! include docs/images ! include *.html ! include *.css ! include *.png global-exclude *.bat - - - --- 1,9 ---- include MANIFEST.in include license.txt ! include docs/* ! include docs/images/* ! include docs/style/* ! include docs/pydoc/* ! include tests/* global-exclude *.bat |
From: Mike C. F. <mcf...@us...> - 2004-05-20 05:20:48
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21003 Modified Files: setup.py Log Message: Metadata for PyPI and version bump to 1.0.0 final Index: setup.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/setup.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** setup.py 6 Jul 2003 21:22:52 -0000 1.3 --- setup.py 20 May 2004 05:20:37 -0000 1.4 *************** *** 53,61 **** os.path.walk( '.', directoryWalker, dataFiles) ### Now the actual set up call setup ( name = "PyDispatcher", ! version = "1.0.0a1", ! description = "Multi-producer-multi-consumer signal dispatching mechanism", author = "Patrick K. O'Brien", author_email = "pyd...@li...", --- 53,91 ---- os.path.walk( '.', directoryWalker, dataFiles) + from sys import hexversion + if hexversion >= 0x2030000: + # work around distutils complaints under Python 2.2.x + extraArguments = { + 'classifiers': [ + """License :: OSI Approved :: BSD License""", + """Programming Language :: Python""", + """Topic :: Software Development :: Libraries :: Python Modules""", + """Intended Audience :: Developers""", + ], + 'download_url': "https://sourceforge.net/project/showfiles.php?group_id=79755", + 'keywords': 'dispatcher,dispatch,event,signal,sender,receiver,propagate,multi-consumer,multi-producer,saferef,robustapply,apply', + 'long_description' : """Dispatcher mechanism for creating event models + + PyDispatcher is an enhanced version of Patrick K. O'Brien's + original dispatcher.py module. It provides the Python + programmer with a robust mechanism for event routing within + various application contexts. + + Included in the package are the robustapply and saferef + modules, which provide the ability to selectively apply + arguments to callable objects and to reference instance + methods using weak-references. + """, + 'platforms': ['Any'], + } + else: + extraArguments = { + } + ### Now the actual set up call setup ( name = "PyDispatcher", ! version = "1.0.0", ! description= "Multi-producer-multi-consumer signal dispatching mechanism", author = "Patrick K. O'Brien", author_email = "pyd...@li...", *************** *** 79,105 **** 'group':'Libraries/Python', 'provides':'python-dispatcher', ! 'requires':"python", # >=2.2 ! }, ! 'register':{ ! #'keywords': 'dispatcher,dispatch,event,signal,sender,receiver,propagate,multi-consumer,multi-producer', ! #'summary':'Multi-producer-multi-consumer signal routing mechanism', ! 'description':"""Dispatcher mechanism for creating event models ! ! PyDispatcher is an enhanced version of Patrick K. O'Brien's ! original dispatcher.py module. It provides the Python ! programmer with a robust mechanism for event routing within ! various application contexts. ! """, ! 'classifiers': [ ! """License :: OSI Approved :: BSD License""", ! """Programming Language :: Python""", ! """Topic :: Software Development :: Libraries :: Python Modules""", ! """Intended Audience :: Developers""", ! ], ! #'download_url': "https://sourceforge.net/project/showfiles.php?group_id=79755", }, }, data_files = dataFiles, cmdclass = {'install_data':smart_install_data}, ) --- 109,120 ---- 'group':'Libraries/Python', 'provides':'python-dispatcher', ! 'requires':"python", }, }, data_files = dataFiles, cmdclass = {'install_data':smart_install_data}, + + # registration metadata + **extraArguments ) |
From: <mcf...@us...> - 2004-02-18 00:39:00
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32424 Modified Files: dispatcher.py Log Message: NameError fix for bug #783157 Index: dispatcher.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/dispatcher.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** dispatcher.py 6 Jul 2003 22:52:32 -0000 1.5 --- dispatcher.py 18 Feb 2004 00:29:46 -0000 1.6 *************** *** 203,207 **** receivers = connections[senderkey][signal] except KeyError: ! raise DispatcherKeyError( """No receivers found for signal %r from sender %r""" %( signal, --- 203,207 ---- receivers = connections[senderkey][signal] except KeyError: ! raise errors.DispatcherKeyError( """No receivers found for signal %r from sender %r""" %( signal, *************** *** 212,216 **** receivers.remove(receiver) except ValueError: ! raise DispatcherKeyError( """No connection to receiver %s for signal %s from sender %s""" %( receiver, --- 212,216 ---- receivers.remove(receiver) except ValueError: ! raise errors.DispatcherKeyError( """No connection to receiver %s for signal %s from sender %s""" %( receiver, |
From: <mcf...@us...> - 2003-12-31 09:02:58
|
Update of /cvsroot/pydispatcher/dispatch/docs In directory sc8-pr-cvs1:/tmp/cvs-serv10644 Modified Files: index.html Log Message: Clarification and expansion of notes regarding the two weakref bugs. Index: index.html =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/docs/index.html,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** index.html 6 Jul 2003 23:00:47 -0000 1.4 --- index.html 31 Dec 2003 09:02:54 -0000 1.5 *************** *** 2,10 **** <html> <head> ! <meta http-equiv="content-type" ! content="text/html; charset=ISO-8859-1"> <title>Python Dispatch Package</title> ! <link rel="stylesheet" type="text/css" href="style/sitestyle.css"> ! <meta name="author" content="Patrick K. O'Brien"> </head> <body> --- 2,10 ---- <html> <head> ! <meta content="text/html; charset=ISO-8859-1" ! http-equiv="content-type"> <title>Python Dispatch Package</title> ! <link href="style/sitestyle.css" type="text/css" rel="stylesheet"> ! <meta content="Patrick K. O'Brien" name="author"> </head> <body> *************** *** 12,16 **** <p class="introduction">PyDispatcher provides the Python programmer with a multiple-producer-multiple-consumer signal-registration and ! routing infrastructure for use in multiple contexts. The mechanism of PyDispatcher started life as a highly rated <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/87056">recipe</a> --- 12,17 ---- <p class="introduction">PyDispatcher provides the Python programmer with a multiple-producer-multiple-consumer signal-registration and ! routing infrastructure for use in multiple contexts. The ! mechanism of PyDispatcher started life as a highly rated <a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/87056">recipe</a> *************** *** 84,91 **** the module to a directory on your PythonPath.<br> </p> ! <p class="technical">Due to problems with the Python 2.2.2 (and ! earlier) weak reference implementation, it is <strong>strongly ! recommended</strong> that you use <strong>Python 2.2.3</strong> or later ! when using PyDispatcher.<br> </p> <h2>Documentation</h2> --- 85,114 ---- the module to a directory on your PythonPath.<br> </p> ! <p class="technical">PyDispatcher represents one of the more involved ! usage patterns for Python weakref objects. We have discovered a few ! problems in weakref operation of which users of the package should be ! aware.<br> ! </p> ! <p class="technical">Python 2.2.2 (and ! earlier) weak reference implementations have a subtle <a ! href="https://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=742911">bug</a> ! in their weakref destructor code which can cause memory access errors ! (aka segfaults) on program shutdown. If you are using Python 2.2, ! it is <strong>strongly ! recommended</strong> that you use <strong>Python 2.2.3</strong> or ! later ! when using PyDispatcher. Note that this will not address the ! following issue.<br> ! </p> ! <p class="technical">Python 2.3.2 (and earlier) has a different (even ! more subtle) <a ! href="http://cvs.sourceforge.net/viewcvs.py/python/python/dist/src/Modules/gc_weakref.txt?rev=2.1&view=auto">bug</a> ! in the weakref destructor code which, again, can cause segfaults. ! If you are using Python 2.3, it is <strong>strongly ! recommended</strong> that you use <strong>Python 2.3.3</strong> or ! later ! when using PyDispatcher. This bug-fix will not be ported back to ! the Python 2.2.x branch, so if you are using Python 2.2.3 you may ! encounter this situation. </p> <h2>Documentation</h2> *************** *** 101,109 **** </p> <p class="footer">A SourceForge Open-Source project: <a ! href="http://sourceforge.net"><img ! src="http://sourceforge.net/sflogo.php?group_id=79755&type=1" style="border: 0px solid ; width: 88px; height: 31px;" ! alt="SourceForge" title="" align="middle" width="88" height="31" ! border="0"></a></p> </body> </html> --- 124,131 ---- </p> <p class="footer">A SourceForge Open-Source project: <a ! href="http://sourceforge.net"><img border="0" height="31" width="88" ! align="middle" title="" alt="SourceForge" style="border: 0px solid ; width: 88px; height: 31px;" ! src="http://sourceforge.net/sflogo.php?group_id=79755&type=1"></a></p> </body> </html> |
From: <mcf...@us...> - 2003-07-06 23:00:49
|
Update of /cvsroot/pydispatcher/dispatch/docs In directory sc8-pr-cvs1:/tmp/cvs-serv16849 Modified Files: index.html Log Message: Added link to pydoc reference for dispatch.dispatcher Index: index.html =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/docs/index.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** index.html 6 Jul 2003 14:22:47 -0000 1.3 --- index.html 6 Jul 2003 23:00:47 -0000 1.4 *************** *** 91,96 **** <h2>Documentation</h2> <p>You can find usage samples in the examples directory of the ! distribution. The dispatcher module's documentation is currently ! the major source of information regarding the usage patterns.<br> </p> <p>PyDispatcher welcomes contributions, suggestions, and feedback from --- 91,97 ---- <h2>Documentation</h2> <p>You can find usage samples in the examples directory of the ! distribution. The dispatcher module's <a ! href="pydoc/dispatch.dispatcher.html">reference documentation</a> is ! currently the major source of information regarding usage.<br> </p> <p>PyDispatcher welcomes contributions, suggestions, and feedback from |
From: <mcf...@us...> - 2003-07-06 22:59:52
|
Update of /cvsroot/pydispatcher/dispatch/docs/pydoc In directory sc8-pr-cvs1:/tmp/cvs-serv16635 Added Files: __init__.py builddocs.py pydoc2.py Log Message: Copied pydoc2 module from OpenGLContext to auto-build reference documentation from the modules. --- NEW FILE: __init__.py --- """pydoc documentation system with enhancements and automatic local builder This package is based on the standard pydoc package, with a few minor enhancements, and a slightly modified format. An automatic mechanism for generating extensive documentation for the OpenGLContext project is provided. """ --- NEW FILE: builddocs.py --- """Script to automatically generate OpenGLContext documentation""" import pydoc2 if __name__ == "__main__": excludes = [ "math", "string", ] stops = [ "OpenGL.Demo.NeHe", "OpenGL.Demo.GLE", "OpenGL.Demo.da", ] modules = [ "dispatch", "weakref", ] pydoc2.PackageDocumentationGenerator( baseModules = modules, destinationDirectory = ".", exclusions = excludes, recursionStops = stops, ).process () --- NEW FILE: pydoc2.py --- """Pydoc sub-class for generating documentation for entire packages""" import pydoc, inspect, os, string import sys, imp, os, stat, re, types, inspect from repr import Repr from string import expandtabs, find, join, lower, split, strip, rfind, rstrip class DefaultFormatter(pydoc.HTMLDoc): def docmodule(self, object, name=None, mod=None, packageContext = None, *ignored): """Produce HTML documentation for a module object.""" name = object.__name__ # ignore the passed-in name parts = split(name, '.') links = [] for i in range(len(parts)-1): links.append( '<a href="%s.html"><font color="#ffffff">%s</font></a>' % (join(parts[:i+1], '.'), parts[i])) linkedname = join(links + parts[-1:], '.') head = '<big><big><strong>%s</strong></big></big>' % linkedname try: path = inspect.getabsfile(object) url = path if sys.platform == 'win32': import nturl2path url = nturl2path.pathname2url(path) filelink = '<a href="file:%s">%s</a>' % (url, path) except TypeError: filelink = '(built-in)' info = [] if hasattr(object, '__version__'): version = str(object.__version__) if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': version = strip(version[11:-1]) info.append('version %s' % self.escape(version)) if hasattr(object, '__date__'): info.append(self.escape(str(object.__date__))) if info: head = head + ' (%s)' % join(info, ', ') result = self.heading( head, '#ffffff', '#7799ee', '<a href=".">index</a><br>' + filelink) modules = inspect.getmembers(object, inspect.ismodule) classes, cdict = [], {} for key, value in inspect.getmembers(object, inspect.isclass): if (inspect.getmodule(value) or object) is object: classes.append((key, value)) cdict[key] = cdict[value] = '#' + key for key, value in classes: for base in value.__bases__: key, modname = base.__name__, base.__module__ module = sys.modules.get(modname) if modname != name and module and hasattr(module, key): if getattr(module, key) is base: if not cdict.has_key(key): cdict[key] = cdict[base] = modname + '.html#' + key funcs, fdict = [], {} for key, value in inspect.getmembers(object, inspect.isroutine): if inspect.isbuiltin(value) or inspect.getmodule(value) is object: funcs.append((key, value)) fdict[key] = '#-' + key if inspect.isfunction(value): fdict[value] = fdict[key] data = [] for key, value in inspect.getmembers(object, pydoc.isdata): if key not in ['__builtins__', '__doc__']: data.append((key, value)) doc = self.markup(pydoc.getdoc(object), self.preformat, fdict, cdict) doc = doc and '<tt>%s</tt>' % doc result = result + '<p>%s</p>\n' % doc packageContext.clean ( classes, object ) packageContext.clean ( funcs, object ) packageContext.clean ( data, object ) if hasattr(object, '__path__'): modpkgs = [] modnames = [] for file in os.listdir(object.__path__[0]): path = os.path.join(object.__path__[0], file) modname = inspect.getmodulename(file) if modname and modname not in modnames: modpkgs.append((modname, name, 0, 0)) modnames.append(modname) elif pydoc.ispackage(path): modpkgs.append((file, name, 1, 0)) modpkgs.sort() contents = self.multicolumn(modpkgs, self.modpkglink) ## result = result + self.bigsection( ## 'Package Contents', '#ffffff', '#aa55cc', contents) result = result + self.moduleSection( object, packageContext) elif modules: contents = self.multicolumn( modules, lambda (key, value), s=self: s.modulelink(value)) result = result + self.bigsection( 'Modules', '#fffff', '#aa55cc', contents) if classes: classlist = map(lambda (key, value): value, classes) contents = [ self.formattree(inspect.getclasstree(classlist, 1), name)] for key, value in classes: contents.append(self.document(value, key, name, fdict, cdict)) result = result + self.bigsection( 'Classes', '#ffffff', '#ee77aa', join(contents)) if funcs: contents = [] for key, value in funcs: contents.append(self.document(value, key, name, fdict, cdict)) result = result + self.bigsection( 'Functions', '#ffffff', '#eeaa77', join(contents)) if data: contents = [] for key, value in data: contents.append(self.document(value, key)) result = result + self.bigsection( 'Data', '#ffffff', '#55aa55', join(contents, '<br>\n')) if hasattr(object, '__author__'): contents = self.markup(str(object.__author__), self.preformat) result = result + self.bigsection( 'Author', '#ffffff', '#7799ee', contents) if hasattr(object, '__credits__'): contents = self.markup(str(object.__credits__), self.preformat) result = result + self.bigsection( 'Credits', '#ffffff', '#7799ee', contents) return result def classlink(self, object, modname): """Make a link for a class.""" name, module = object.__name__, sys.modules.get(object.__module__) if hasattr(module, name) and getattr(module, name) is object: return '<a href="%s.html#%s">%s</a>' % ( module.__name__, name, name ) return pydoc.classname(object, modname) def moduleSection( self, object, packageContext ): """Create a module-links section for the given object (module)""" modules = inspect.getmembers(object, inspect.ismodule) packageContext.clean ( modules, object ) packageContext.recurseScan( modules ) if hasattr(object, '__path__'): modpkgs = [] modnames = [] for file in os.listdir(object.__path__[0]): path = os.path.join(object.__path__[0], file) modname = inspect.getmodulename(file) if modname and modname not in modnames: modpkgs.append((modname, object.__name__, 0, 0)) modnames.append(modname) elif pydoc.ispackage(path): modpkgs.append((file, object.__name__, 1, 0)) modpkgs.sort() # do more recursion here... for (modname, name, ya,yo) in modpkgs: packageContext.addInteresting( join( (object.__name__, modname), '.')) items = [] for (modname, name, ispackage,isshadowed) in modpkgs: try: # get the actual module object... ## if modname == "events": ## import pdb ## pdb.set_trace() module = pydoc.safeimport( "%s.%s"%(name,modname) ) description, documentation = pydoc.splitdoc( inspect.getdoc( module )) if description: items.append( """%s -- %s"""% ( self.modpkglink( (modname, name, ispackage, isshadowed) ), description, ) ) else: items.append( self.modpkglink( (modname, name, ispackage, isshadowed) ) ) except: items.append( self.modpkglink( (modname, name, ispackage, isshadowed) ) ) contents = string.join( items, '<br>') result = self.bigsection( 'Package Contents', '#ffffff', '#aa55cc', contents) elif modules: contents = self.multicolumn( modules, lambda (key, value), s=self: s.modulelink(value)) result = self.bigsection( 'Modules', '#fffff', '#aa55cc', contents) else: result = "" return result class AlreadyDone(Exception): pass class PackageDocumentationGenerator: """A package document generator creates documentation for an entire package using pydoc's machinery. baseModules -- modules which will be included and whose included and children modules will be considered fair game for documentation destinationDirectory -- the directory into which the HTML documentation will be written recursion -- whether to add modules which are referenced by and/or children of base modules exclusions -- a list of modules whose contents will not be shown in any other module, commonly such modules as OpenGL.GL, wxPython.wx etc. recursionStops -- a list of modules which will explicitly stop recursion (i.e. they will never be included), even if they are children of base modules. formatter -- allows for passing in a custom formatter see DefaultFormatter for sample implementation. """ def __init__ ( self, baseModules, destinationDirectory = ".", recursion = 1, exclusions = (), recursionStops = (), formatter = None ): self.destinationDirectory = os.path.abspath( destinationDirectory) self.exclusions = {} self.warnings = [] self.baseSpecifiers = {} self.completed = {} self.recursionStops = {} self.recursion = recursion for stop in recursionStops: self.recursionStops[ stop ] = 1 self.pending = [] for exclusion in exclusions: try: self.exclusions[ exclusion ]= pydoc.locate ( exclusion) except pydoc.ErrorDuringImport, value: self.warn( """Unable to import the module %s which was specified as an exclusion module"""% (repr(exclusion))) self.formatter = formatter or DefaultFormatter() for base in baseModules: self.addBase( base ) def warn( self, message ): """Warnings are used for recoverable, but not necessarily ignorable conditions""" self.warnings.append (message) def info (self, message): """Information/status report""" print message def addBase(self, specifier): """Set the base of the documentation set, only children of these modules will be documented""" try: self.baseSpecifiers [specifier] = pydoc.locate ( specifier) self.pending.append (specifier) except pydoc.ErrorDuringImport, value: self.warn( """Unable to import the module %s which was specified as a base module"""% (repr(specifier))) def addInteresting( self, specifier): """Add a module to the list of interesting modules""" if self.checkScope( specifier): ## print "addInteresting", specifier self.pending.append (specifier) else: self.completed[ specifier] = 1 def checkScope (self, specifier): """Check that the specifier is "in scope" for the recursion""" if not self.recursion: return 0 items = string.split (specifier, ".") stopCheck = items [:] while stopCheck: name = string.join(items, ".") if self.recursionStops.get( name): return 0 elif self.completed.get (name): return 0 del stopCheck[-1] while items: if self.baseSpecifiers.get( string.join(items, ".")): return 1 del items[-1] # was not within any given scope return 0 def process( self ): """Having added all of the base and/or interesting modules, proceed to generate the appropriate documentation for each module in the appropriate directory, doing the recursion as we go.""" try: while self.pending: try: if self.completed.has_key( self.pending[0] ): raise AlreadyDone( self.pending[0] ) self.info( """Start %s"""% (repr(self.pending[0]))) object = pydoc.locate ( self.pending[0] ) self.info( """ ... found %s"""% (repr(object.__name__))) except AlreadyDone: pass except pydoc.ErrorDuringImport, value: self.info( """ ... FAILED %s"""% (repr( value))) self.warn( """Unable to import the module %s"""% (repr(self.pending[0]))) except (SystemError, SystemExit), value: self.info( """ ... FAILED %s"""% (repr( value))) self.warn( """Unable to import the module %s"""% (repr(self.pending[0]))) except Exception, value: self.info( """ ... FAILED %s"""% (repr( value))) self.warn( """Unable to import the module %s"""% (repr(self.pending[0]))) else: page = self.formatter.page( pydoc.describe(object), self.formatter.docmodule( object, object.__name__, packageContext = self, ) ) file = open ( os.path.join( self.destinationDirectory, self.pending[0] + ".html", ), 'w', ) file.write(page) file.close() self.completed[ self.pending[0]] = object del self.pending[0] finally: for item in self.warnings: print item def clean (self, objectList, object): """callback from the formatter object asking us to remove those items in the key, value pairs where the object is imported from one of the excluded modules""" for key, value in objectList[:]: for excludeObject in self.exclusions.values(): if hasattr( excludeObject, key ) and excludeObject is not object: if ( getattr( excludeObject, key) is value or (hasattr( excludeObject, '__name__') and excludeObject.__name__ == "Numeric" ) ): objectList[:] = [ (k,o) for k,o in objectList if k != key ] def recurseScan(self, objectList): """Process the list of modules trying to add each to the list of interesting modules""" for key, value in objectList: self.addInteresting( value.__name__ ) if __name__ == "__main__": excludes = [ "OpenGL.GL", "OpenGL.GLU", "OpenGL.GLUT", "OpenGL.GLE", "OpenGL.GLX", "wxPython.wx", "Numeric", "_tkinter", "Tkinter", ] modules = [ "OpenGLContext.debug", ## "wxPython.glcanvas", ## "OpenGL.Tk", ## "OpenGL", ] PackageDocumentationGenerator( baseModules = modules, destinationDirectory = "z:\\temp", exclusions = excludes, ).process () |
From: <mcf...@us...> - 2003-07-06 22:57:43
|
Update of /cvsroot/pydispatcher/dispatch/docs/pydoc In directory sc8-pr-cvs1:/tmp/cvs-serv16374/pydoc Log Message: Directory /cvsroot/pydispatcher/dispatch/docs/pydoc added to the repository |
From: <mcf...@us...> - 2003-07-06 22:53:23
|
Update of /cvsroot/pydispatcher/dispatch/examples In directory sc8-pr-cvs1:/tmp/cvs-serv15859/examples Modified Files: simple_sample.py Log Message: Moved "active" part of the sample into a "main block" to allow documentation to run w/out triggering the demo. Index: simple_sample.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/examples/simple_sample.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** simple_sample.py 6 Jul 2003 14:23:54 -0000 1.1 --- simple_sample.py 6 Jul 2003 22:53:21 -0000 1.2 *************** *** 1,2 **** --- 1,3 ---- + """Simple sample showing basic usage pattern""" from dispatch import dispatcher *************** *** 40,76 **** Node(), ] ! ! # Establish some "routing" connections ! dispatcher.connect ( ! doSomethingUseful, ! signal = DO_LOTS, ! sender = ourObjects[0], ! ) ! dispatcher.connect ( ! doSomethingElse, ! signal = DO_SOMETHING, ! sender = ourObjects[0], ! ) ! dispatcher.connect( ! doDefault, ! signal = dispatcher.Any, # this is actually the default, ! sender = ourObjects[0], ! ) ! print "Sending DO_LOTS to first object" ! dispatcher.send( ! signal = DO_LOTS, ! sender = ourObjects[0], ! table = "Table Argument", ! ) ! print "Sending DO_SOMETHING to first object" ! dispatcher.send( ! signal = DO_SOMETHING, ! sender = ourObjects[0], ! table = "Table Argument", ! ) ! print "Sending DO_SOMETHING_ELSE to first object" ! dispatcher.send( ! signal = DO_SOMETHING_ELSE, ! sender = ourObjects[0], ! table = "Table Argument", ! ) --- 41,77 ---- Node(), ] ! if __name__ == "__main__": ! # Establish some "routing" connections ! dispatcher.connect ( ! doSomethingUseful, ! signal = DO_LOTS, ! sender = ourObjects[0], ! ) ! dispatcher.connect ( ! doSomethingElse, ! signal = DO_SOMETHING, ! sender = ourObjects[0], ! ) ! dispatcher.connect( ! doDefault, ! signal = dispatcher.Any, # this is actually the default, ! sender = ourObjects[0], ! ) ! print "Sending DO_LOTS to first object" ! dispatcher.send( ! signal = DO_LOTS, ! sender = ourObjects[0], ! table = "Table Argument", ! ) ! print "Sending DO_SOMETHING to first object" ! dispatcher.send( ! signal = DO_SOMETHING, ! sender = ourObjects[0], ! table = "Table Argument", ! ) ! print "Sending DO_SOMETHING_ELSE to first object" ! dispatcher.send( ! signal = DO_SOMETHING_ELSE, ! sender = ourObjects[0], ! table = "Table Argument", ! ) |
From: <mcf...@us...> - 2003-07-06 22:52:35
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv15773 Modified Files: dispatcher.py Added Files: errors.py Log Message: Factored errors into their own module, made _Any and _Anonymous not get overridden by their singleton instances so that they provide documentation in PyDoc docs, eliminated extraneous import of exceptions. --- NEW FILE: errors.py --- """Error types for dispatcher mechanism """ class DispatcherError(Exception): """Base class for all Dispatcher errors""" class DispatcherKeyError(KeyError, DispatcherError): """Error raised when unknown (sender,signal) set specified""" class DispatcherTypeError(TypeError, DispatcherError): """Error raised when inappropriate signal-type specified (None)""" Index: dispatcher.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/dispatcher.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dispatcher.py 6 Jul 2003 20:30:28 -0000 1.4 --- dispatcher.py 6 Jul 2003 22:52:32 -0000 1.5 *************** *** 8,19 **** Any -- Singleton used to signal either "Any Sender" or ! "Any Signal". See documentation of the Any object. Anonymous -- Singleton used to signal "Anonymous Sender" ! See documentation of the Anonymous object. ! DispatcherError -- Base class for Dispatcher errors ! DispatcherKeyError -- Raised on attempts to disconnect ! a connection which doesn't exist ! DispatcherTypeError -- Raised on use of None as a signal ! during connect/disconnect Internal attributes: --- 8,14 ---- Any -- Singleton used to signal either "Any Sender" or ! "Any Signal". See documentation of the _Any class. Anonymous -- Singleton used to signal "Anonymous Sender" ! See documentation of the _Anonymous class. Internal attributes: *************** *** 32,37 **** """ from __future__ import generators ! import exceptions, types, weakref ! from dispatch import saferef, robustapply __author__ = "Patrick K. O'Brien <po...@or...>" --- 27,32 ---- """ from __future__ import generators ! import types, weakref ! from dispatch import saferef, robustapply, errors __author__ = "Patrick K. O'Brien <po...@or...>" *************** *** 39,50 **** __version__ = "$Revision$"[11:-2] - - class DispatcherError(Exception): - """Base class for all Dispatcher errors""" - class DispatcherKeyError(KeyError, DispatcherError): - """Error raised when unknown (sender,signal) set specified""" - class DispatcherTypeError(TypeError, DispatcherError): - """Error raised when inappropriate signal-type specified (None)""" - try: True --- 34,37 ---- *************** *** 58,62 **** return self.__class__.__name__ ! class Any(_Parameter): """Singleton used to signal either "Any Sender" or "Any Signal" --- 45,49 ---- return self.__class__.__name__ ! class _Any(_Parameter): """Singleton used to signal either "Any Sender" or "Any Signal" *************** *** 66,72 **** a particular sender/signal. """ ! Any = Any() ! class Anonymous(_Parameter): """Singleton used to signal "Anonymous Sender" --- 53,59 ---- a particular sender/signal. """ ! Any = _Any() ! class _Anonymous(_Parameter): """Singleton used to signal "Anonymous Sender" *************** *** 86,90 **** being used everywhere. """ ! Anonymous = Anonymous() WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref) --- 73,77 ---- being used everywhere. """ ! Anonymous = _Anonymous() WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref) *************** *** 148,152 **** """ if signal is None: ! raise DispatcherTypeError( 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) --- 135,139 ---- """ if signal is None: ! raise errors.DispatcherTypeError( 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) *************** *** 208,212 **** """ if signal is None: ! raise DispatcherTypeError( 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) --- 195,199 ---- """ if signal is None: ! raise errors.DispatcherTypeError( 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ) |
From: <mcf...@us...> - 2003-07-06 21:22:55
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv4655 Modified Files: setup.py Added Files: MANIFEST.in Log Message: Added automatic scanning for non-python files to include, created manifest file for source distribution specification. --- NEW FILE: MANIFEST.in --- include MANIFEST.in include license.txt include *.py include docs include docs/style include docs/images include *.html include *.css include *.png global-exclude *.bat Index: setup.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/setup.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** setup.py 1 Jul 2003 04:51:25 -0000 1.2 --- setup.py 6 Jul 2003 21:22:52 -0000 1.3 *************** *** 8,15 **** if __name__ == "__main__": ! import sys,os, string from distutils.sysconfig import * from distutils.core import setup ### Now the actual set up call setup ( --- 8,56 ---- if __name__ == "__main__": ! import sys,os, string, fnmatch from distutils.sysconfig import * from distutils.core import setup + ############## + ## Following is from Pete Shinners, + ## apparently it will work around the reported bug on + ## some unix machines where the data files are copied + ## to weird locations if the user's configuration options + ## were entered during the wrong phase of the moon :) . + from distutils.command.install_data import install_data + class smart_install_data(install_data): + def run(self): + #need to change self.install_dir to the library dir + install_cmd = self.get_finalized_command('install') + self.install_dir = getattr(install_cmd, 'install_lib') + # should create the directory if it doesn't exist!!! + return install_data.run(self) + ############## + ### The following automates the inclusion of files while avoiding problems with UNIX + ### where case sensitivity matters. + dataFiles = [] + excludedTypes = ('.py','.pyc','.pyo','.db','.gz','.bat', ".cvsignore") + excludedDirectories = ('build','dist','cvs') + def nonPythonFile( file ): + """Is the fully-qualified name a non-python file""" + if os.path.isfile( file ): + return (os.path.splitext( file )[1]).lower() not in excludedTypes + def directoryWalker( argument, directory, files, prefix = "dispatch"): + """Walk the particular directory searching for non-python files + + prefix -- prefix directory appended to the destination + directories, normally the name of the target package + """ + if os.path.split(directory.lower())[-1] in excludedDirectories: + return + result = [] + for file in files: + file = os.path.join(directory,file ) + if nonPythonFile( file ): + result.append( file ) + if result: + argument.append((os.path.join(prefix,directory), result)) + os.path.walk( '.', directoryWalker, dataFiles) + ### Now the actual set up call setup ( *************** *** 17,21 **** version = "1.0.0a1", description = "Multi-producer-multi-consumer signal dispatching mechanism", ! author = "Patrick K. O'Brien, Mike Fletcher", author_email = "pyd...@li...", url = "http://pydispatcher.sourceforge.net", --- 58,62 ---- version = "1.0.0a1", description = "Multi-producer-multi-consumer signal dispatching mechanism", ! author = "Patrick K. O'Brien", author_email = "pyd...@li...", url = "http://pydispatcher.sourceforge.net", *************** *** 28,36 **** packages = [ 'dispatch', ! 'dispatch.test', ], ! # non python files of examples options = { 'sdist':{'use_defaults':0, 'force_manifest':1}, 'bdist_rpm':{ 'group':'Libraries/Python', --- 69,79 ---- packages = [ 'dispatch', ! 'dispatch.tests', ! 'dispatch.examples', ], ! options = { 'sdist':{'use_defaults':0, 'force_manifest':1}, + "install_lib":{"compile":0, "optimize":0}, 'bdist_rpm':{ 'group':'Libraries/Python', *************** *** 57,60 **** --- 100,105 ---- }, }, + data_files = dataFiles, + cmdclass = {'install_data':smart_install_data}, ) |
From: <mcf...@us...> - 2003-07-06 21:22:16
|
Update of /cvsroot/pydispatcher/dispatch/examples In directory sc8-pr-cvs1:/tmp/cvs-serv4603/examples Added Files: __init__.py Log Message: Made the examples directory a package --- NEW FILE: __init__.py --- """Example scripts for the dispatch project """ |
From: <mcf...@us...> - 2003-07-06 20:30:52
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv26346 Modified Files: __init__.py Log Message: Fixed the license declaration Index: __init__.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/__init__.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** __init__.py 1 Jul 2003 03:52:28 -0000 1.1.1.1 --- __init__.py 6 Jul 2003 20:30:50 -0000 1.2 *************** *** 3,6 **** __version__ = "1.0.0" __author__ = "Patrick K. O'Brien" ! __license__ = "XXX Fix me!" --- 3,6 ---- __version__ = "1.0.0" __author__ = "Patrick K. O'Brien" ! __license__ = "BSD-style, see license.txt for details" |
From: <mcf...@us...> - 2003-07-06 20:30:31
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv26311 Modified Files: dispatcher.py Log Message: More documentation, created explicit error hierarchy to allow for catching individual error types, and to allow catching general error types without explicitly importing dispatcher. Index: dispatcher.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/dispatcher.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dispatcher.py 6 Jul 2003 15:00:11 -0000 1.3 --- dispatcher.py 6 Jul 2003 20:30:28 -0000 1.4 *************** *** 11,17 **** Anonymous -- Singleton used to signal "Anonymous Sender" See documentation of the Anonymous object. ! DispatcherError -- Raised on use of None as a signal ! or attempts to disconnect when there is no current ! connection. Internal attributes: --- 11,19 ---- Anonymous -- Singleton used to signal "Anonymous Sender" See documentation of the Anonymous object. ! DispatcherError -- Base class for Dispatcher errors ! DispatcherKeyError -- Raised on attempts to disconnect ! a connection which doesn't exist ! DispatcherTypeError -- Raised on use of None as a signal ! during connect/disconnect Internal attributes: *************** *** 38,44 **** ! class DispatcherError(exceptions.Exception): ! def __init__(self, args=None): ! self.args = args try: --- 40,49 ---- ! class DispatcherError(Exception): ! """Base class for all Dispatcher errors""" ! class DispatcherKeyError(KeyError, DispatcherError): ! """Error raised when unknown (sender,signal) set specified""" ! class DispatcherTypeError(TypeError, DispatcherError): ! """Error raised when inappropriate signal-type specified (None)""" try: *************** *** 93,97 **** """Connect receiver to sender for signal ! receiver -- a callable Python object if weak is True, then receiver must be weak-referencable --- 98,104 ---- """Connect receiver to sender for signal ! receiver -- a callable Python object which is to receive ! messages/signals/events. Receivers must be hashable ! objects. if weak is True, then receiver must be weak-referencable *************** *** 116,120 **** if Any, receiver will receive any signal from the ! registered sender. Otherwise must be a hashable Python object other than --- 123,128 ---- if Any, receiver will receive any signal from the ! indicated sender (which might also be Any, but is not ! necessarily Any). Otherwise must be a hashable Python object other than *************** *** 123,132 **** sender -- the sender to which the receiver should respond ! if Any, receiver will receive registered signals from ! any sender. ! if Anonymous, receiver will only receive registered ! signals which do not specify a sender, or specify ! Anonymous explicitly as the sender. Otherwise can be any python object. --- 131,140 ---- sender -- the sender to which the receiver should respond ! if Any, receiver will receive the indicated signals ! from any sender. ! if Anonymous, receiver will only receive indicated ! signals from send/sendExact which do not specify a ! sender, or specify Anonymous explicitly as the sender. Otherwise can be any python object. *************** *** 137,144 **** is false, then strong references will be used. ! returns None """ if signal is None: ! raise DispatcherError, 'signal cannot be None' receiverID = id( receiver ) if weak: receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) --- 145,154 ---- is false, then strong references will be used. ! returns None, may raise DispatcherTypeError """ if signal is None: ! raise DispatcherTypeError( ! 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ! ) receiverID = id( receiver ) if weak: receiver = saferef.safeRef(receiver, onDelete=_removeReceiver) *************** *** 172,181 **** def disconnect(receiver, signal=Any, sender=Any, weak=True): ! """Disconnect receiver from sender for signal. ! ! Disconnecting is not required. The use of disconnect is the same as for ! connect, only in reverse. Think of it as undoing a previous connection.""" if signal is None: ! raise DispatcherError, 'signal cannot be None' if weak: receiver = saferef.safeRef(receiver) senderkey = id(sender) --- 182,214 ---- def disconnect(receiver, signal=Any, sender=Any, weak=True): ! """Disconnect receiver from sender for signal ! ! receiver -- the registered receiver to disconnect ! signal -- the registered signal to disconnect ! sender -- the registered sender to disconnect ! weak -- the weakref state to disconnect ! ! disconnect reverses the process of connect, ! the semantics for the individual elements are ! logically equivalent to a tuple of ! (receiver, signal, sender, weak) used as a key ! to be deleted from the internal routing tables. ! (The actual process is slightly more complex ! but the semantics are basically the same). ! ! Note: ! Using disconnect is not required to cleanup ! routing when an object is deleted, the framework ! will remove routes for deleted objects ! automatically. It's only necessary to disconnect ! if you want to stop routing to a live object. ! ! returns None, may raise DispatcherTypeError or ! DispatcherKeyError ! """ if signal is None: ! raise DispatcherTypeError( ! 'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender) ! ) if weak: receiver = saferef.safeRef(receiver) senderkey = id(sender) *************** *** 183,195 **** receivers = connections[senderkey][signal] except KeyError: ! raise DispatcherError, \ ! 'No receivers for signal %s from sender %s' % \ ! (repr(signal), sender) try: receivers.remove(receiver) except ValueError: ! raise DispatcherError, \ ! 'No connection to receiver %s for signal %s from sender %s' % \ ! (receiver, repr(signal), sender) _cleanupConnections(senderkey, signal) --- 216,235 ---- receivers = connections[senderkey][signal] except KeyError: ! raise DispatcherKeyError( ! """No receivers found for signal %r from sender %r""" %( ! signal, ! sender ! ) ! ) try: receivers.remove(receiver) except ValueError: ! raise DispatcherKeyError( ! """No connection to receiver %s for signal %s from sender %s""" %( ! receiver, ! signal, ! sender ! ) ! ) _cleanupConnections(senderkey, signal) *************** *** 238,243 **** This gets all receivers which should receive ! signal from sender, each receiver should exist ! only once in the resulting generator """ receivers = {} --- 278,283 ---- This gets all receivers which should receive ! the given signal from sender, each receiver should ! be produced only once by the resulting generator """ receivers = {} *************** *** 265,275 **** """Send signal from sender to all connected receivers. ! Return a list of tuple pairs [(receiver, response), ... ]. ! If sender is None, signal is sent anonymously, note that ! the default *registration* is for Any sender, not anonymous; ! default registration receives default send, but any ! registration which specifies a signal does *not* receive the ! default anonymous send """ # Call each receiver with whatever arguments it can accept. --- 305,338 ---- """Send signal from sender to all connected receivers. ! signal -- (hashable) signal value, see connect for details ! ! sender -- the sender of the signal ! if Any, only receivers registered for Any will receive ! the message. ! ! if Anonymous, only receivers registered to receive ! messages from Anonymous or Any will receive the message ! ! Otherwise can be any python object (normally one ! registered with a connect if you actually want ! something to occur). ! ! arguments -- positional arguments which will be passed to ! *all* receivers. Note that this may raise TypeErrors ! if the receivers do not allow the particular arguments. ! Note also that arguments are applied before named ! arguments, so they should be used with care. ! ! named -- named arguments which will be filtered according ! to the parameters of the receivers to only provide those ! acceptable to the receiver. ! ! Return a list of tuple pairs [(receiver, response), ... ] ! ! if any receiver raises an error, the error propagates back ! through send, terminating the dispatch loop, so it is quite ! possible to not have all receivers called if a raises an ! error. """ # Call each receiver with whatever arguments it can accept. *************** *** 289,293 **** """Send signal only to those receivers registered for exact message ! See send for details """ responses = [] --- 352,359 ---- """Send signal only to those receivers registered for exact message ! sendExact allows for avoiding Any/Anonymous registered ! handlers, sending only to those receivers explicitly ! registered for a particular signal on a particular ! sender. """ responses = [] |
From: <mcf...@us...> - 2003-07-06 15:00:17
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv17277 Modified Files: dispatcher.py Log Message: Added quite a bit of documentation, down to the "connect" function so far. Index: dispatcher.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/dispatcher.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dispatcher.py 1 Jul 2003 04:25:44 -0000 1.2 --- dispatcher.py 6 Jul 2003 15:00:11 -0000 1.3 *************** *** 1,16 **** ! """Provides global signal dispatching services. ! Slightly modified version for vrml and OpenGLContext ! packages. Modifications: ! eliminate the cast to string for the signal objects, ! which allows for non-string signal values. ! provide back-reference set for senders/recievers ! which dramatically improves performance during system ! shutdown or deallocation of nodes ! refactoring of saferef into seperate module to allow ! for general reuse. """ from __future__ import generators --- 1,31 ---- ! """Multiple-producer-multiple-consumer signal-dispatching ! dispatcher is the core of the PyDispatcher system, ! providing the primary API and the core logic for the ! system. ! Module attributes of note: ! Any -- Singleton used to signal either "Any Sender" or ! "Any Signal". See documentation of the Any object. ! Anonymous -- Singleton used to signal "Anonymous Sender" ! See documentation of the Anonymous object. ! DispatcherError -- Raised on use of None as a signal ! or attempts to disconnect when there is no current ! connection. ! Internal attributes: ! WEAKREF_TYPES -- tuple of types/classes which represent ! weak references to receivers, and thus must be de- ! referenced on retrieval to retrieve the callable ! object ! connections -- { senderkey (id) : { signal : [receivers...]}} ! senders -- { senderkey (id) : weakref(sender) } ! used for cleaning up sender references on sender ! deletion ! sendersBack -- { receiverkey (id) : [senderkey (id)...] } ! used for cleaning up receiver references on receiver ! deletion, (considerably speeds up the cleanup process ! vs. the original code.) """ from __future__ import generators *************** *** 38,45 **** return self.__class__.__name__ ! class Any(_Parameter): pass Any = Any() ! class Anonymous(_Parameter): pass Anonymous = Anonymous() --- 53,84 ---- return self.__class__.__name__ ! class Any(_Parameter): ! """Singleton used to signal either "Any Sender" or "Any Signal" ! ! The Any object can be used with connect, disconnect, ! send, or sendExact to signal that the parameter given ! Any should react to all senders/signals, not just ! a particular sender/signal. ! """ Any = Any() ! class Anonymous(_Parameter): ! """Singleton used to signal "Anonymous Sender" ! ! The Anonymous object is used to signal that the sender ! of a message is not specified (as distinct from being ! "any sender"). Registering callbacks for Anonymous ! will only receive messages sent without senders. Sending ! with anonymous will only send messages to those receivers ! registered for Any or Anonymous. ! ! Note: ! The default sender for connect is Any, while the ! default sender for send is Anonymous. This has ! the effect that if you do not specify any senders ! in either function then all messages are routed ! as though there was a single sender (Anonymous) ! being used everywhere. ! """ Anonymous = Anonymous() *************** *** 52,66 **** def connect(receiver, signal=Any, sender=Any, weak=True): ! """Connect receiver to sender for signal. ! If sender is Any, receiver will receive signal from any sender. ! If signal is Any, receiver will receive any signal from sender. ! If sender is None, receiver will receive signal from anonymous. ! If signal is Any and sender is None, receiver will receive any ! signal from anonymous. ! If signal is Any and sender is Any, receiver will receive any ! signal from any sender. ! If weak is true, weak references will be used.""" if signal is None: raise DispatcherError, 'signal cannot be None' --- 91,142 ---- def connect(receiver, signal=Any, sender=Any, weak=True): ! """Connect receiver to sender for signal ! ! receiver -- a callable Python object ! ! if weak is True, then receiver must be weak-referencable ! (more precisely saferef.safeRef() must be able to create ! a reference to the receiver). ! Receivers are fairly flexible in their specification, ! as the machinery in the robustApply module takes care ! of most of the details regarding figuring out appropriate ! subsets of the sent arguments to apply to a given ! receiver. ! ! Note: ! if receiver is itself a weak reference (a callable), ! it will be de-referenced by the system's machinery, ! so *generally* weak references are not suitable as ! receivers, though some use might be found for the ! facility whereby a higher-level library passes in ! pre-weakrefed receiver references. ! ! signal -- the signal to which the receiver should respond ! ! if Any, receiver will receive any signal from the ! registered sender. ! ! Otherwise must be a hashable Python object other than ! None (DispatcherError raised on None). ! ! sender -- the sender to which the receiver should respond + if Any, receiver will receive registered signals from + any sender. + + if Anonymous, receiver will only receive registered + signals which do not specify a sender, or specify + Anonymous explicitly as the sender. + + Otherwise can be any python object. + + weak -- whether to use weak references to the receiver + By default, the module will attempt to use weak + references to the receiver objects. If this parameter + is false, then strong references will be used. + + returns None + """ if signal is None: raise DispatcherError, 'signal cannot be None' *************** *** 119,123 **** def getReceivers( sender = Any, signal = Any ): ! """Get list of receivers from global tables""" try: return connections[id(sender)][signal] --- 195,215 ---- def getReceivers( sender = Any, signal = Any ): ! """Get list of receivers from global tables ! ! This utility function allows you to retrieve the ! raw list of receivers from the connections table ! for the given sender and signal pair. ! ! Note: ! there is no guarantee that this is the actual list ! stored in the connections table, so the value ! should be treated as a simple iterable/truth value ! rather than, for instance a list to which you ! might append new records. ! ! Normally you would use liveReceivers( getReceivers( ...)) ! to retrieve the actual receiver objects as an iterable ! object. ! """ try: return connections[id(sender)][signal] *************** *** 126,130 **** def liveReceivers(receivers): ! """Filter sequence of receivers to get resolved, live receivers""" for receiver in receivers: if isinstance( receiver, WEAKREF_TYPES): --- 218,228 ---- def liveReceivers(receivers): ! """Filter sequence of receivers to get resolved, live receivers ! ! This is a generator which will iterate over ! the passed sequence, checking for weak references ! and resolving them, then returning all live ! receivers. ! """ for receiver in receivers: if isinstance( receiver, WEAKREF_TYPES): |
From: <mcf...@us...> - 2003-07-06 14:23:57
|
Update of /cvsroot/pydispatcher/dispatch/examples In directory sc8-pr-cvs1:/tmp/cvs-serv13076 Added Files: simple_sample.py Log Message: Added a simple sample usage script. Could use considerably more of this kind of thing. Could probably use more documentation in this particular script as well. --- NEW FILE: simple_sample.py --- from dispatch import dispatcher def doSomethingUseful( table, signal, sender ): """Sample method to receive signals""" print ' doSomethingUseful', repr(table), signal, sender def doSomethingElse( signal, **named ): """Sample method to receive signals This method demonstrates the use of the **named parameter, which allows a method to receive all remaining parameters from the send call. """ print ' doSomethingElse', named def doDefault( ): """Sample method to receive All signals Note that this function will be registered for all signals from a given object. It does not have the same interface as any of the other functions registered for those signals. The system will automatically determine the appropriate calling signature for the function. """ print ' doDefault (no arguments)' class Node(object): """Sample object to send signals, note lack of dispatcher-aware code""" def __init__( self, name="an object" ): self.name = name def __repr__( self ): return "%s( %r )"%( self.__class__.__name__, self.name ) DO_LOTS = 0 DO_SOMETHING = ('THIS','IS','A','MORE','COMPLEX','SIGNAL') DO_SOMETHING_ELSE = Node() ourObjects = [ Node(), Node(), Node(), ] # Establish some "routing" connections dispatcher.connect ( doSomethingUseful, signal = DO_LOTS, sender = ourObjects[0], ) dispatcher.connect ( doSomethingElse, signal = DO_SOMETHING, sender = ourObjects[0], ) dispatcher.connect( doDefault, signal = dispatcher.Any, # this is actually the default, sender = ourObjects[0], ) print "Sending DO_LOTS to first object" dispatcher.send( signal = DO_LOTS, sender = ourObjects[0], table = "Table Argument", ) print "Sending DO_SOMETHING to first object" dispatcher.send( signal = DO_SOMETHING, sender = ourObjects[0], table = "Table Argument", ) print "Sending DO_SOMETHING_ELSE to first object" dispatcher.send( signal = DO_SOMETHING_ELSE, sender = ourObjects[0], table = "Table Argument", ) |
From: <mcf...@us...> - 2003-07-06 14:23:03
|
Update of /cvsroot/pydispatcher/dispatch/examples In directory sc8-pr-cvs1:/tmp/cvs-serv12968/examples Log Message: Directory /cvsroot/pydispatcher/dispatch/examples added to the repository |
From: <mcf...@us...> - 2003-07-06 14:22:50
|
Update of /cvsroot/pydispatcher/dispatch/docs In directory sc8-pr-cvs1:/tmp/cvs-serv12916/docs Modified Files: index.html Log Message: Began work on a "what it does for you" section, simple acquisition/installation instructions, link to mailing list added. Index: index.html =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/docs/index.html,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** index.html 2 Jul 2003 03:11:22 -0000 1.2 --- index.html 6 Jul 2003 14:22:47 -0000 1.3 *************** *** 21,26 **** various applications.<br> </p> <p>PyDispatcher welcomes contributions, suggestions, and feedback from ! users.<br> </p> <p class="footer">A SourceForge Open-Source project: <a --- 21,101 ---- various applications.<br> </p> + <p>To be more concrete about what PyDispatcher does for you:<br> + </p> + <ul> + <li>provides a centralized service for delivering messages to + registered objects (in the local process). It allows you to + register any number of functions (callable objects) which can receive + signals from senders.</li> + <ul> + <li>registration can be for all senders, particular sending + objects, or "anonymous" messages (messages where the sender is None)<br> + </li> + <li>registration can be for any signal, or particular signals</li> + <li>a single signal will be delivered to all appropriate registered + receivers, so that multiple registrations do not interfere with each + other<br> + </li> + </ul> + <li>there is no requirement for the sender or receiver to be + dispatcher-aware. Any Python object save the None object can act + as a sender, and any callable object can act as a receiver. There + is no need to inherit from a particular class or provide a particular + interface on the object.<br> + </li> + <li>the system uses weak references to receivers wherever possible</li> + <ul> + <li>object lifetimes are not affected by PyDispatcher registrations + (that is, when your object goes away, the registrations related to the + object also go away). <br> + </li> + <li>references to common transient objects (in particular instance + methods) are stored as compound weak references. <br> + </li> + <li>weak references can be disabled on a + registration-by-registration basis</li> + </ul> + <li>allows rich signal types, signals are simply hashable objects + used to store and retrieve sub-tables, they are otherwise opaque to the + dispatcher mechanism</li> + <li>allows sending more information when sending than any particular + receiver can handle, dispatcher automatically culls those arguments + which are not appropriate for the particular receiver. This + allows registering very simple functions dealing with general messages, + while still allowing natural passing of arguments to higher level + functions.<br> + </li> + </ul> + <p>The dispatcher mechanism is particularly useful when constructing + Model-View-Controller style applications where it is not desirable to + have the Model objects aware of the event model.</p> + <h2>Acquisition and Installation</h2> + <p>PyDispatcher is available as a standard Python distutils + installation package from the SourceForge project <a + href="https://sourceforge.net/project/showfiles.php?group_id=79755">file + repository</a>. To install, unzip the source archive into a + temporary directory and run:<br> + </p> + <pre>python setup.py install<br></pre> + <p>PyDispatcher does not include any binary packages, so there should + be no issues in installation. To use the <a + href="https://sourceforge.net/cvs/?group_id=79755">CVS version</a> of + PyDispatcher (useful for developers of PyDispatcher), simply check out + the module to a directory on your PythonPath.<br> + </p> + <p class="technical">Due to problems with the Python 2.2.2 (and + earlier) weak reference implementation, it is <strong>strongly + recommended</strong> that you use <strong>Python 2.2.3</strong> or later + when using PyDispatcher.<br> + </p> + <h2>Documentation</h2> + <p>You can find usage samples in the examples directory of the + distribution. The dispatcher module's documentation is currently + the major source of information regarding the usage patterns.<br> + </p> <p>PyDispatcher welcomes contributions, suggestions, and feedback from ! users in the pydispatcher-dev <a ! href="http://lists.sourceforge.net/lists/listinfo/pydispatcher-devel">mailing ! list</a>.<br> </p> <p class="footer">A SourceForge Open-Source project: <a |
From: <mcf...@us...> - 2003-07-02 03:13:18
|
Update of /cvsroot/pydispatcher/dispatch/docs In directory sc8-pr-cvs1:/tmp/cvs-serv15938/docs Modified Files: index.html Log Message: Fix trivial grammar error (unchecked-in change from yesterday) Index: index.html =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/docs/index.html,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** index.html 1 Jul 2003 04:15:39 -0000 1.1 --- index.html 2 Jul 2003 03:11:22 -0000 1.2 *************** *** 21,25 **** various applications.<br> </p> ! <p>PyDispatcher welcomes contributions, suggestions, feedback from users.<br> </p> --- 21,25 ---- various applications.<br> </p> ! <p>PyDispatcher welcomes contributions, suggestions, and feedback from users.<br> </p> |
From: <mcf...@us...> - 2003-07-02 02:03:47
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv8036 Added Files: license.txt Log Message: Introduction of BSD license.txt --- NEW FILE: license.txt --- PyDispatcher License Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The name of Patrick K. O'Brien, or the name of any Contributor, may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
From: <mcf...@us...> - 2003-07-01 04:51:28
|
Update of /cvsroot/pydispatcher/dispatch In directory sc8-pr-cvs1:/tmp/cvs-serv10468 Modified Files: setup.py Log Message: Eliminated some unused mechanisms, added the beginning of a PyPI registration set, though it doesn't appear to work at the moment. Index: setup.py =================================================================== RCS file: /cvsroot/pydispatcher/dispatch/setup.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup.py 1 Jul 2003 04:16:13 -0000 1.1 --- setup.py 1 Jul 2003 04:51:25 -0000 1.2 *************** *** 10,57 **** import sys,os, string from distutils.sysconfig import * ! from distutils.core import setup,Extension ! from distutils.command.build_ext import build_ext ! from distutils.command.install import install ! from distutils.command.install_data import install_data ! ##from my_install_data import * - ############## - ## Following is from Pete Shinners, - ## apparently it will work around the reported bug on - ## some unix machines where the data files are copied - ## to weird locations if the user's configuration options - ## were entered during the wrong phase of the moon :) . - from distutils.command.install_data import install_data - class smart_install_data(install_data): - def run(self): - #need to change self.install_dir to the library dir - install_cmd = self.get_finalized_command('install') - self.install_dir = getattr(install_cmd, 'install_lib') - # should create the directory if it doesn't exist!!! - return install_data.run(self) - ############## - ### The following automates the inclusion of files while avoiding problems with UNIX - ### where case sensitivity matters. - dataFiles = [] - excludedTypes = ('.py','.pyc','.pyo', '.db', '.max','.gz','.bat') - def nonPythonFile( file ): - if string.lower( file ) == 'cvs': - return 0 - else: - return (os.path.splitext( file )[1]).lower() not in excludedTypes - dataDirectories = [ - '.', - 'tests', - ] - for directory in dataDirectories: - finalFiles = [] - for file in os.listdir( directory): - fullFile = os.path.join( directory, file ) - if os.path.isfile(fullFile) and nonPythonFile(fullFile): - finalFiles.append (os.path.join(directory, file)) - if finalFiles: - dataFiles.append ( - (os.path.join('dispatch',directory),finalFiles) - ) ### Now the actual set up call setup ( --- 10,15 ---- import sys,os, string from distutils.sysconfig import * ! from distutils.core import setup ### Now the actual set up call setup ( *************** *** 73,78 **** ], # non python files of examples ! data_files = dataFiles, ! cmdclass = {'install_data':smart_install_data}, ) --- 31,60 ---- ], # non python files of examples ! options = { ! 'sdist':{'use_defaults':0, 'force_manifest':1}, ! 'bdist_rpm':{ ! 'group':'Libraries/Python', ! 'provides':'python-dispatcher', ! 'requires':"python", # >=2.2 ! }, ! 'register':{ ! #'keywords': 'dispatcher,dispatch,event,signal,sender,receiver,propagate,multi-consumer,multi-producer', ! #'summary':'Multi-producer-multi-consumer signal routing mechanism', ! 'description':"""Dispatcher mechanism for creating event models ! ! PyDispatcher is an enhanced version of Patrick K. O'Brien's ! original dispatcher.py module. It provides the Python ! programmer with a robust mechanism for event routing within ! various application contexts. ! """, ! 'classifiers': [ ! """License :: OSI Approved :: BSD License""", ! """Programming Language :: Python""", ! """Topic :: Software Development :: Libraries :: Python Modules""", ! """Intended Audience :: Developers""", ! ], ! #'download_url': "https://sourceforge.net/project/showfiles.php?group_id=79755", ! }, ! }, ) |