|
[Webware-checkins] r7216 - in Webware/trunk: DocSupport
MiddleKit/Design MiddleKit/Run MiscUtils PSP PSP/Examples
TaskKit bin
From: <updates@we...> - 2008-02-08 02:54
|
Author: chrisz
Date: Thu Feb 7 19:54:12 2008
New Revision: 7216
Modified:
Webware/trunk/DocSupport/ClassList.py
Webware/trunk/DocSupport/FileList.py
Webware/trunk/DocSupport/PyFontify.py
Webware/trunk/DocSupport/buildhtml.py
Webware/trunk/MiddleKit/Design/MSSQLSQLGenerator.py
Webware/trunk/MiddleKit/Run/SQLObjectStore.py
Webware/trunk/MiscUtils/BasicDateTime.py
Webware/trunk/MiscUtils/DictForArgs.py
Webware/trunk/MiscUtils/Error.py
Webware/trunk/MiscUtils/MixIn.py
Webware/trunk/MiscUtils/NamedValueAccess.py
Webware/trunk/MiscUtils/PickleCache.py
Webware/trunk/MiscUtils/PickleRPC.py
Webware/trunk/PSP/Examples/PSPExamplePage.py
Webware/trunk/PSP/Generators.py
Webware/trunk/PSP/PSPParser.py
Webware/trunk/TaskKit/Task.py
Webware/trunk/bin/MakeAppWorkDir.py
Webware/trunk/bin/pystats.py
Log:
Some more code clean-up.
Modified: Webware/trunk/DocSupport/ClassList.py
==============================================================================
--- Webware/trunk/DocSupport/ClassList.py (original)
+++ Webware/trunk/DocSupport/ClassList.py Thu Feb 7 19:54:12 2008
@@ -9,7 +9,7 @@
import os, re, sys, time
from glob import glob
-from types import *
+from types import StringType
def EmptyString(klass):
Modified: Webware/trunk/DocSupport/FileList.py
==============================================================================
--- Webware/trunk/DocSupport/FileList.py (original)
+++ Webware/trunk/DocSupport/FileList.py Thu Feb 7 19:54:12 2008
@@ -1,14 +1,15 @@
#!/usr/bin/env python
-"""
-FileList.py
+
+"""FileList.py
A quick, hacky script to contruct a file list from a set of Python files.
+
"""
import os, re, sys
from glob import glob
-from types import *
+from types import StringType
class FileList:
Modified: Webware/trunk/DocSupport/PyFontify.py
==============================================================================
--- Webware/trunk/DocSupport/PyFontify.py (original)
+++ Webware/trunk/DocSupport/PyFontify.py Thu Feb 7 19:54:12 2008
@@ -11,6 +11,7 @@
(tag, startindex, endindex, sublist)
tag is one of ('comment', 'string', 'keyword', 'function', 'class')
sublist is not used, hence always None.
+
"""
# Based on FontText.py by Mitchell S. Chapman,
Modified: Webware/trunk/DocSupport/buildhtml.py
==============================================================================
--- Webware/trunk/DocSupport/buildhtml.py (original)
+++ Webware/trunk/DocSupport/buildhtml.py Thu Feb 7 19:54:12 2008
@@ -8,8 +8,7 @@
# Copied from the Docutils 0.4 tools directory
-"""
-Generates .html from all the .txt files in a directory.
+"""Generate .html from all the .txt files in a directory.
Ordinary .txt files are understood to be standalone reStructuredText.
Files named ``pep-*.txt`` are interpreted as reStructuredText PEPs.
Modified: Webware/trunk/MiddleKit/Design/MSSQLSQLGenerator.py
==============================================================================
--- Webware/trunk/MiddleKit/Design/MSSQLSQLGenerator.py (original)
+++ Webware/trunk/MiddleKit/Design/MSSQLSQLGenerator.py Thu Feb 7 19:54:12 2008
@@ -368,7 +368,7 @@
preSql = str('declare %s as int; set %s = %s;\n' % (
refVarName, refVarName, objId))
sqlForValue = classId + ',' + refVarName
- return (preSql, sqlForValue)
+ return preSql, sqlForValue
else:
return sql
Modified: Webware/trunk/MiddleKit/Run/SQLObjectStore.py
==============================================================================
--- Webware/trunk/MiddleKit/Run/SQLObjectStore.py (original)
+++ Webware/trunk/MiddleKit/Run/SQLObjectStore.py Thu Feb 7 19:54:12 2008
@@ -210,7 +210,7 @@
conn, cur = self.executeSQL('select id, name from _MKClassIds;')
try:
klassesById = {}
- for (id, name) in cur.fetchall():
+ for id, name in cur.fetchall():
assert id, "Id must be a non-zero int. id=%r, name=%r" % (id, name)
try:
klass = self._model.klass(name)
Modified: Webware/trunk/MiscUtils/BasicDateTime.py
==============================================================================
--- Webware/trunk/MiscUtils/BasicDateTime.py (original)
+++ Webware/trunk/MiscUtils/BasicDateTime.py Thu Feb 7 19:54:12 2008
@@ -402,7 +402,7 @@
"""
sql = self.isoformat()
wday = calendar.weekday(int(sql[0:4]), int(sql[5:7]), int(sql[8:10]))
- return (int(sql[0:4]), int(sql[5:7]), int(sql[8:10]), 0, 0, 0, wday, 0, -1)
+ return int(sql[0:4]), int(sql[5:7]), int(sql[8:10]), 0, 0, 0, wday, 0, -1
def now(self):
"""Return the current date and time as a datetime."""
Modified: Webware/trunk/MiscUtils/DictForArgs.py
==============================================================================
--- Webware/trunk/MiscUtils/DictForArgs.py (original)
+++ Webware/trunk/MiscUtils/DictForArgs.py Thu Feb 7 19:54:12 2008
@@ -1,10 +1,9 @@
-"""
-DictForArgs.py
-
+"""DictForArgs.py
See the doc string for the DictForArgs() function.
Also, there is a test suite in Testing/TestDictForArgs.py
+
"""
@@ -14,11 +13,14 @@
class DictForArgsError(Exception):
pass
+
def _SyntaxError(s):
raise DictForArgsError, 'Syntax error: %s' % repr(s)
+
def DictForArgs(s):
- """
+ """Build dictionary from arguments.
+
Takes an input such as:
x=3
name="foo"
@@ -41,7 +43,8 @@
Will raise DictForArgsError if the string is invalid.
- See also: PyDictForArgs() and ExpandDictWithExtras() in this module
+ See also: PyDictForArgs() and ExpandDictWithExtras() in this module.
+
"""
s = string.strip(s)
@@ -109,7 +112,7 @@
i = 0
while i < matchesLen:
match = matches[i]
- if i+1 < matchesLen:
+ if i + 1 < matchesLen:
peekMatch = matches[i+1]
else:
peekMatch = None
@@ -121,7 +124,7 @@
i += 1
continue
if peekMatch.re is equalsRE:
- if i+2 < matchesLen:
+ if i + 2 < matchesLen:
target = matches[i+2]
if target.re is nameRE or target.re is stringRE:
value = target.group()
@@ -147,7 +150,8 @@
from string import letters
def PyDictForArgs(s):
- """
+ """Build dictionary from arguments.
+
Takes an input such as:
x=3
name="foo"
@@ -167,7 +171,8 @@
Returns {} for an empty string.
- See also: DictForArgs() and ExpandDictWithExtras() in this module
+ See also: DictForArgs() and ExpandDictWithExtras() in this module.
+
"""
if s:
s = s.strip()
@@ -188,16 +193,22 @@
def ExpandDictWithExtras(dict, key='Extras', delKey=1, dictForArgs=DictForArgs):
- """
- Returns a dictionary with the 'Extras' column expanded by DictForArgs(). For example, given:
+ """Return a dictionary with the 'Extras' column expanded by DictForArgs().
+
+ For example, given:
{ 'Name': 'foo', 'Extras': 'x=1 y=2' }
The return value is:
{ 'Name': 'foo', 'x': '1', 'y': '2' }
- The key argument controls what key in the dictionary is used to hold the extra arguments. The delKey argument controls whether that key and its corresponding value are retained.
+ The key argument controls what key in the dictionary is used to hold
+ the extra arguments. The delKey argument controls whether that key and
+ its corresponding value are retained.
The same dictionary may be returned if there is no extras key.
- The most typical use of this function is to pass a row from a DataTable that was initialized from a CSV file (e.g., a spreadsheet or tabular file). FormKit and MiddleKit both use CSV files and allow for an Extras column to specify attributes that occur infrequently.
- """
+ The most typical use of this function is to pass a row from a DataTable
+ that was initialized from a CSV file (e.g., a spreadsheet or tabular file).
+ FormKit and MiddleKit both use CSV files and allow for an Extras column
+ to specify attributes that occur infrequently.
+ """
if dict.has_key(key):
newDict = {}
# We use the following for loop rather than newDict.update()
Modified: Webware/trunk/MiscUtils/Error.py
==============================================================================
--- Webware/trunk/MiscUtils/Error.py (original)
+++ Webware/trunk/MiscUtils/Error.py Thu Feb 7 19:54:12 2008
@@ -2,8 +2,12 @@
class Error(UserDict):
- """
- An error is a dictionary-like object, containing a specific user-readable error message and an object associated with it. Since Error inherits UserDict, other informative values can be arbitrarily attached to errors. For this reason, subclassing Error is rare.
+ """Universal error class.
+
+ An error is a dictionary-like object, containing a specific
+ user-readable error message and an object associated with it.
+ Since Error inherits UserDict, other informative values can be arbitrarily
+ attached to errors. For this reason, subclassing Error is rare.
Example:
err = Error(user, 'Invalid password.')
@@ -14,7 +18,8 @@
print err.object()
print err.message()
- When creating errors, you can pass None for both the object and the message. You can also pass additional values, which are then included in the error:
+ When creating errors, you can pass None for both the object and the message.
+ You can also pass additional values, which are then included in the error:
>>> err = Error(None, 'Too bad.', timestamp=time.time())
>>> err.keys()
['timestamp']
@@ -24,10 +29,17 @@
>>> err = Error(None, 'Too bad.', info)
Or you could even do both if you needed to.
+
"""
def __init__(self, object, message, valueDict={}, **valueArgs):
- """ Initializes an error with the object the error occurred for, and the user-readable error message. The message should be self sufficient such that if printed by itself, the user would understand it. """
+ """Initialize the error.
+
+ Takes the object the error occurred for, and the user-readable
+ error message. The message should be self sufficient such that
+ if printed by itself, the user would understand it.
+
+ """
UserDict.__init__(self)
self._object = object
self._message = message
@@ -41,7 +53,8 @@
return self._message
def __repr__(self):
- return 'ERROR(object=%s; message=%s; data=%s)' % (repr(self._object), repr(self._message), repr(self.data))
+ return 'ERROR(object=%s; message=%s; data=%s)' % (
+ repr(self._object), repr(self._message), repr(self.data))
def __str__(self):
return 'ERROR: %s' % self._message
Modified: Webware/trunk/MiscUtils/MixIn.py
==============================================================================
--- Webware/trunk/MiscUtils/MixIn.py (original)
+++ Webware/trunk/MiscUtils/MixIn.py Thu Feb 7 19:54:12 2008
@@ -1,74 +1,96 @@
from types import MethodType
import sys
-if hasattr(sys, 'version_info') and sys.version_info[0] >= 2:
- def MixIn(pyClass, mixInClass, makeAncestor=0, mixInSuperMethods=0):
- """
- Mixes in the attributes of the mixInClass into the pyClass. These attributes are typically methods (but don't have to be). Note that private attributes, denoted by a double underscore, are not mixed in. Collisions are resolved by the mixInClass' attribute overwriting the pyClass'. This gives mix-ins the power to override the behavior of the pyClass.
-
- After using MixIn(), instances of the pyClass will respond to the messages of the mixInClass.
-
- An assertion fails if you try to mix in a class with itself.
-
- The pyClass will be given a new attribute mixInsForCLASSNAME which is a list of all mixInClass' that have ever been installed, in the order they were installed. You may find this useful for inspection and debugging.
-
- You are advised to install your mix-ins at the start up of your program, prior to the creation of any objects. This approach will result in less headaches. But like most things in Python, you're free to do whatever you're willing to live with. :-)
-
- There is a bitchin' article in the Linux Journal, April 2001, "Using Mix-ins with Python" by Chuck Esterbrook which gives a thorough treatment of this topic.
-
- An example, that resides in Webware, is MiddleKit.Core.ModelUser.py, which install mix-ins for SQL adapters. Search for "MixIn(".
-
- If makeAncestor is 1, then a different technique is employed: the mixInClass is made the first base class of the pyClass. You probably don't need to use this and if you do, be aware that your mix-in can no longer override attributes/methods in pyClass.
-
- If mixInSuperMethods is 1, then support will be enabled for you to be able to call the original or
- "parent" method from the mixed-in method. This is done like so:
-
- class MyMixInClass:
- def foo(self):
- MyMixInClass.mixInSuperFoo(self) # call the original method
- # now do whatever you want
-
- This function only exists if you are using Python 2.0 or later. Python 1.5.2 has a problem where functions (as in aMethod.im_func) are tied to their class, when in fact, they should be totally generic with only the methods being tied to their class. Apparently this was fixed in Py 2.0.
- """
- assert mixInClass is not pyClass, 'mixInClass = %r, pyClass = %r' % (mixInClass, pyClass)
- if makeAncestor:
- if mixInClass not in pyClass.__bases__:
- pyClass.__bases__ = (mixInClass,) + pyClass.__bases__
- else:
- # Recursively traverse the mix-in ancestor classes in order
- # to support inheritance
- baseClasses = list(mixInClass.__bases__)
- baseClasses.reverse()
- for baseClass in baseClasses:
- MixIn(pyClass, baseClass)
-
- # Track the mix-ins made for a particular class
- attrName = 'mixInsFor' + pyClass.__name__
- mixIns = getattr(pyClass, attrName, None)
- if mixIns is None:
- mixIns = []
- setattr(pyClass, attrName, mixIns)
-
- # Make sure we haven't done this before
- # Er, woops. Turns out we like to mix-in more than once sometimes.
- #assert not mixInClass in mixIns, 'pyClass = %r, mixInClass = %r, mixIns = %r' % (pyClass, mixInClass, mixIns)
-
- # Record our deed for future inspection
- mixIns.append(mixInClass)
-
- # Install the mix-in methods into the class
- for name in dir(mixInClass):
- # skip private members, but not __repr__ et al:
- if not (name.startswith('__') and not name.endswith('__')) and name not in readOnlyNames:
- member = getattr(mixInClass, name)
-
- if type(member) is MethodType and mixInSuperMethods:
- if hasattr(pyClass, name):
- origmember = getattr(pyClass, name)
- setattr(mixInClass, 'mixInSuper' + name[0].upper() + name[1:], origmember)
- if type(member) is MethodType:
- member = member.im_func
- setattr(pyClass, name, member)
+def MixIn(pyClass, mixInClass, makeAncestor=0, mixInSuperMethods=0):
+ """Mixes in the attributes of the mixInClass into the pyClass.
+
+ These attributes are typically methods (but don't have to be).
+ Note that private attributes, denoted by a double underscore,
+ are not mixed in. Collisions are resolved by the mixInClass'
+ attribute overwriting the pyClass'. This gives mix-ins the power
+ to override the behavior of the pyClass.
+
+ After using MixIn(), instances of the pyClass will respond to
+ the messages of the mixInClass.
+
+ An assertion fails if you try to mix in a class with itself.
+
+ The pyClass will be given a new attribute mixInsForCLASSNAME
+ which is a list of all mixInClass' that have ever been installed,
+ in the order they were installed. You may find this useful
+ for inspection and debugging.
+
+ You are advised to install your mix-ins at the start up
+ of your program, prior to the creation of any objects.
+ This approach will result in less headaches. But like most things
+ in Python, you're free to do whatever you're willing to live with. :-)
+
+ There is a bitchin' article in the Linux Journal, April 2001,
+ "Using Mix-ins with Python" by Chuck Esterbrook,
+ which gives a thorough treatment of this topic.
+
+ An example, that resides in Webware, is MiddleKit.Core.ModelUser.py,
+ which install mix-ins for SQL adapters. Search for "MixIn(".
+
+ If makeAncestor is 1, then a different technique is employed:
+ the mixInClass is made the first base class of the pyClass.
+ You probably don't need to use this and if you do, be aware that your
+ mix-in can no longer override attributes/methods in pyClass.
+
+ If mixInSuperMethods is 1, then support will be enabled for you to
+ be able to call the original or "parent" method from the mixed-in method.
+ This is done like so:
+
+ class MyMixInClass:
+ def foo(self):
+ MyMixInClass.mixInSuperFoo(self) # call the original method
+ # now do whatever you want
+
+ """
+ assert mixInClass is not pyClass, \
+ 'mixInClass = %r, pyClass = %r' % (mixInClass, pyClass)
+ if makeAncestor:
+ if mixInClass not in pyClass.__bases__:
+ pyClass.__bases__ = (mixInClass,) + pyClass.__bases__
+ else:
+ # Recursively traverse the mix-in ancestor classes in order
+ # to support inheritance
+ baseClasses = list(mixInClass.__bases__)
+ baseClasses.reverse()
+ for baseClass in baseClasses:
+ MixIn(pyClass, baseClass)
+
+ # Track the mix-ins made for a particular class
+ attrName = 'mixInsFor' + pyClass.__name__
+ mixIns = getattr(pyClass, attrName, None)
+ if mixIns is None:
+ mixIns = []
+ setattr(pyClass, attrName, mixIns)
+
+ # Make sure we haven't done this before (Er, woops.
+ # Turns out we like to mix-in more than once sometimes.)
+ # assert not mixInClass in mixIns, \
+ # 'pyClass = %r, mixInClass = %r, mixIns = %r' % (
+ # pyClass, mixInClass, mixIns)
+
+ # Record our deed for future inspection
+ mixIns.append(mixInClass)
+
+ # Install the mix-in methods into the class
+ for name in dir(mixInClass):
+ # skip private members, but not __repr__ et al:
+ if not (name.startswith('__') and not name.endswith('__')
+ ) and name not in readOnlyNames:
+ member = getattr(mixInClass, name)
+
+ if type(member) is MethodType and mixInSuperMethods:
+ if hasattr(pyClass, name):
+ origmember = getattr(pyClass, name)
+ setattr(mixInClass, 'mixInSuper'
+ + name[0].upper() + name[1:], origmember)
+ if type(member) is MethodType:
+ member = member.im_func
+ setattr(pyClass, name, member)
readOnlyNames = '__doc__'.split()
Modified: Webware/trunk/MiscUtils/NamedValueAccess.py
==============================================================================
--- Webware/trunk/MiscUtils/NamedValueAccess.py (original)
+++ Webware/trunk/MiscUtils/NamedValueAccess.py Thu Feb 7 19:54:12 2008
@@ -34,7 +34,7 @@
* Benchmarking: Set this up in a new file:
Testing/BenchNamedValueAccess.py
- so we can experiment with caching vs. not and other techniques.
+ so we can experiment with caching vs. not and other techniques.
PAST DESIGN DECISIONS
@@ -390,7 +390,7 @@
if type(obj) is types.DictType:
try:
value = obj[listOfKeys[0]]
- except: # @@ 2000-03-03 ce: this exception should be more specific. probably nameerror or indexerror
+ except KeyError:
if default is None:
raise NamedValueAccessError, \
'Unknown key (%s) in dictionary.' % listOfKeys[0]
Modified: Webware/trunk/MiscUtils/PickleCache.py
==============================================================================
--- Webware/trunk/MiscUtils/PickleCache.py (original)
+++ Webware/trunk/MiscUtils/PickleCache.py Thu Feb 7 19:54:12 2008
@@ -74,10 +74,8 @@
class PickleCache:
- """
- Just a simple abstract base class for PickleCacheReader and
- PickleCacheWriter.
- """
+ """Simple abstract base class for PickleCacheReader and PickleCacheWriter."""
+
_verbose = verbose
def picklePath(self, filename):
@@ -87,8 +85,13 @@
class PickleCacheReader(PickleCache):
def read(self, filename, pickleVersion=1, source=None, verbose=None):
- """
- Returns the data from the pickle cache version of the filename, if it can read. Otherwise returns None which also indicates that writePickleCache() should be subsequently called after the original file is read.
+ """Read data from pickle cache.
+
+ Returns the data from the pickle cache version of the filename,
+ if it can read. Otherwise returns None, which also indicates
+ that writePickleCache() should be subsequently called after
+ the original file is read.
+
"""
if verbose is None:
v = self._verbose
@@ -99,11 +102,13 @@
assert filename
if not os.path.exists(filename):
- # if v: print 'cannot find %r' % filename
+ if v:
+ print 'Cannot find %r.' % filename
open(filename) # to get a properly constructed IOError
if not havePython22OrGreater:
- # if v: print 'Python version is too old for this. Returning None.'
+ if v:
+ print 'Python version is too old for this. Returning None.'
return None
didReadPickle = 0
@@ -114,61 +119,78 @@
picklePath = self.picklePath(filename)
if os.path.exists(picklePath):
if os.path.getmtime(picklePath) < os.path.getmtime(filename):
- # if v: print 'cache is out of date'
+ if v:
+ print 'Cache is out of date.'
shouldDeletePickle = 1
else:
try:
- # if v: print 'about to open for read %r' % picklePath
+ if v:
+ print 'About to open for read %r.' % picklePath
file = open(picklePath, 'rb')
except IOError, e:
- # if v: print 'cannot open cache file: %s: %s' % (e.__class__.__name__, e)
+ if v:
+ print 'Cannot open cache file: %s: %s.' % (
+ e.__class__.__name__, e)
pass
else:
try:
- # if v: print 'about to load'
+ if v:
+ print 'about to load'
dict = load(file)
except EOFError:
- # if v: print 'EOFError - not loading'
+ if v:
+ print 'EOFError - not loading'
shouldDeletePickle = 1
except Exception, exc:
- print 'WARNING: %s: %s: %s' % (self.__class__.__name__, exc.__class__, exc)
+ print 'WARNING: %s: %s: %s' % (
+ self.__class__.__name__, exc.__class__, exc)
shouldDeletePickle = 1
else:
file.close()
- # if v: print 'finished reading'
- assert isinstance(dict, DictType), 'type=%r dict=%r' % (type(dict), dict)
+ if v:
+ print 'Finished reading.'
+ assert isinstance(dict, DictType), 'type=%r dict=%r' % (
+ type(dict), dict)
for key in ('source', 'data', 'pickle version', 'python version'):
assert dict.has_key(key), key
if source and dict['source'] != source:
- # if v: print 'not from required source (%s): %s' % (source, dict['source'])
+ if v:
+ print 'Not from required source (%s): %s.' % (
+ source, dict['source'])
shouldDeletePickle = 1
elif dict['pickle version'] != pickleVersion:
- # if v: print 'pickle version (%i) does not match expected (%i)' % (dict['pickle version'], pickleVersion)
+ if v:
+ print 'Pickle version (%i) does not match expected (%i).' % (
+ dict['pickle version'], pickleVersion)
shouldDeletePickle = 1
elif dict['python version'] != sys.version_info:
- # if v: print 'python version %s does not match current %s' % (dict['python version'], sys.version_info)
+ if v:
+ print 'Python version %s does not match current %s.' % (
+ dict['python version'], sys.version_info)
shouldDeletePickle = 1
else:
- # if v: print 'all tests pass. accepting data'
- if v > 1:
- print 'display full dict:'
- pprint(dict)
+ if v:
+ print 'All tests pass, accepting data.'
+ if v > 1:
+ print 'Display full dict:'
+ pprint(dict)
data = dict['data']
didReadPickle = 1
- # delete the pickle file if suggested by previous conditions
+ # Delete the pickle file if suggested by previous conditions
if shouldDeletePickle:
try:
- # if v: print 'attempting to remove pickle cache file'
+ if v:
+ print 'Attempting to remove pickle cache file.'
os.remove(picklePath)
except OSError, e:
if v:
- print 'failed to remove: %s: %s' % (
+ print 'Failed to remove: %s: %s' % (
e.__class__.__name__, e)
pass
if v:
- print 'done reading data'
+ print 'Done reading data.'
print
return data
@@ -184,12 +206,13 @@
else:
v = verbose
if v:
- print '>> PickleCacheWriter.write() - verbose is on'
+ print '>> PickleCacheWriter.write() - verbose is on.'
assert filename
sourceTimestamp = os.path.getmtime(filename)
if not havePython22OrGreater:
- # if v: print 'Python version is too old for this. Returning None.'
+ if v:
+ print 'Python version is too old for this. Returning None.'
return None
picklePath = self.picklePath(filename)
@@ -200,11 +223,11 @@
'data': data,
}
if v > 1:
- print 'display full dict:'
+ print 'Display full dict:'
pprint(dict)
try:
if v:
- print 'about to open for write %r' % picklePath
+ print 'About to open for write %r.' % picklePath
file = open(picklePath, 'wb')
except IOError, e:
if v:
@@ -214,23 +237,23 @@
while 1:
dump(dict, file, 1) # 1 = binary format
file.close()
- # make sure the cache has a newer timestamp, otherwise the cache
+ # Make sure the cache has a newer timestamp, otherwise the cache
# will just get ignored and rewritten next time.
if os.path.getmtime(picklePath) == sourceTimestamp:
if v:
- print 'timestamps are identical.' \
- ' sleeping %0.2f seconds' % self._writeSleepInterval
+ print 'Timestamps are identical,' \
+ ' sleeping %0.2f seconds.' % self._writeSleepInterval
time.sleep(self._writeSleepInterval)
file = open(picklePath, 'w')
else:
break
if v:
- print 'done writing data'
+ print 'Done writing data.'
print
-# define module level convenience functions:
+# Define module level convenience functions:
_reader = PickleCacheReader()
readPickleCache = _reader.read
_writer = PickleCacheWriter()
Modified: Webware/trunk/MiscUtils/PickleRPC.py
==============================================================================
--- Webware/trunk/MiscUtils/PickleRPC.py (original)
+++ Webware/trunk/MiscUtils/PickleRPC.py Thu Feb 7 19:54:12 2008
@@ -119,17 +119,15 @@
from xmlrpclib.xmlrpclib import ProtocolError as _PE
except ImportError:
from xmlrpclib import ProtocolError as _PE
-# @@ 2002-01-31 ce: should this be caught somewhere for special handling? Perhaps in XMLRPCServlet?
+# @@ 2002-01-31 ce: should this be caught somewhere for special handling?
+# Perhaps in XMLRPCServlet?
class ProtocolError(ResponseError, _PE):
pass
class RequestError(Error):
- """
- These are errors originally raised by the server complaining about
- malformed requests.
- """
+ """Errors originally raised by the server complaining about malformed requests."""
pass
@@ -142,39 +140,44 @@
def __repr__(self):
content = self.content
- return '%s: Content type is not text/x-python-pickled-dict\nheaders = %s\ncontent =\n%s' % (
- self.__class__.__name__, self.headers, content)
+ return '%s: Content type is not text/x-python-pickled-dict\n' \
+ ' headers = %s\ncontent =\n%s' % (
+ self.__class__.__name__, self.headers, content)
__str__ = __repr__
class SafeUnpickler:
- """
+ """Safe unpickler.
+
For security reasons, we don't want to allow just anyone to unpickle
anything. That can cause arbitrary code to be executed.
- So this SafeUnpickler base class is used to control
- what can be unpickled. By default it doesn't let you unpickle
- any class instances at all, but you can create subclass that
- overrides allowedGlobals().
+ So this SafeUnpickler base class is used to control what can be unpickled.
+ By default it doesn't let you unpickle any class instances at all,
+ but you can create subclass that overrides allowedGlobals().
Note that the PickleRPCServlet class in WebKit is derived from this class
and uses its load() and loads() methods to do all unpickling.
+
"""
def allowedGlobals(self):
- """
+ """Allowed class names.
+
Must return a list of (moduleName, klassName) tuples for all
classes that you want to allow to be unpickled.
Example:
return [('mx.DateTime', '_DT')]
allows mx.DateTime instances to be unpickled.
+
"""
return []
def findGlobal(self, module, klass):
if (module, klass) not in self.allowedGlobals():
- raise UnpicklingError, 'For security reasons, you can\'t unpickle objects from module %s with type %s' % (module, klass)
+ raise UnpicklingError, 'For security reasons, you can\'t unpickle' \
+ ' objects from module %s with type %s.' % (module, klass)
globals = {}
exec 'from %s import %s as theClass' % (module, klass) in globals
return globals['theClass']
@@ -199,19 +202,19 @@
uri is the connection point on the server, given as
scheme://host/target.
- The standard implementation always supports the "http" scheme. If
- SSL socket support is available (Python 2.0), it also supports
- "https".
+ The standard implementation always supports the "http" scheme.
+ If SSL socket support is available (Py 2.0), it also supports "https".
If the target part and the slash preceding it are both omitted,
"/PickleRPC" is assumed.
See the module doc string for more information.
- """
- def __init__(self, uri, transport=None, verbose=0, binary=1, compressRequest=1, acceptCompressedResponse=1):
- # establish a "logical" server connection
+ """
+ def __init__(self, uri, transport=None, verbose=0, binary=1,
+ compressRequest=1, acceptCompressedResponse=1):
+ """Establish a "logical" server connection."""
# get the url
import urllib
type, uri = urllib.splittype(uri)
@@ -234,9 +237,7 @@
self._acceptCompressedResponse = acceptCompressedResponse
def _request(self, methodName, args, keywords):
- """
- Call a method on the remote server.
- """
+ """Call a method on the remote server."""
request = {
'version': 1,
'action': 'call',
@@ -254,15 +255,9 @@
else:
compressed = 0
- response = self._transport.request(
- self._host,
- self._handler,
- request,
- verbose=self._verbose,
- binary=self._binary,
- compressed=compressed,
- acceptCompressedResponse=self._acceptCompressedResponse
- )
+ response = self._transport.request(self._host, self._handler, request,
+ verbose=self._verbose, binary=self._binary, compressed=compressed,
+ acceptCompressedResponse=self._acceptCompressedResponse)
return response
@@ -286,8 +281,8 @@
# magic method dispatcher
return _Method(self._requestValue, name)
- # note: to call a remote object with an non-standard name, use
- # result getattr(server, "strange-python-name")(args)
+ # note: to call a remote object with an non-standard name,
+ # use result getattr(server, "strange-python-name")(args)
ServerProxy = Server # be like xmlrpclib for those who might guess or expect it
@@ -295,9 +290,10 @@
class _Method:
- """
- Some magic to bind a Pickle-RPC method to an RPC server.
+ """Some magic to bind a Pickle-RPC method to an RPC server.
+
Supports "nested" methods (e.g. examples.getStateName).
+
"""
def __init__(self, send, name):
@@ -312,9 +308,7 @@
class Transport(SafeUnpickler):
- """
- Handles an HTTP transaction to a Pickle-RPC server.
- """
+ """Handle an HTTP transaction to a Pickle-RPC server."""
# client identifier (may be overridden)
user_agent = "PickleRPC/%s (by http://webware.sf.net/)" % __version__
@@ -343,7 +337,8 @@
self.verbose = verbose
- if h.headers['content-type'] not in ['text/x-python-pickled-dict', 'application/x-python-binary-pickled-dict']:
+ if h.headers['content-type'] not in ['text/x-python-pickled-dict',
+ 'application/x-python-binary-pickled-dict']:
headers = h.headers.headers
content = h.getfile().read()
raise InvalidContentTypeError(headers, content)
@@ -404,9 +399,7 @@
class SafeTransport(Transport):
- """
- Handles an HTTPS transaction to a Pickle-RPC server.
- """
+ """Handle an HTTPS transaction to a Pickle-RPC server."""
def make_connection(self, host):
# create a HTTPS connection object from a host descriptor
Modified: Webware/trunk/PSP/Examples/PSPExamplePage.py
==============================================================================
--- Webware/trunk/PSP/Examples/PSPExamplePage.py (original)
+++ Webware/trunk/PSP/Examples/PSPExamplePage.py Thu Feb 7 19:54:12 2008
@@ -9,7 +9,12 @@
return "PSP Examples"
def scripts(self):
- """Create a list of dictionaries, where each dictionary stores information about a particular script."""
+ """Get list of PSP scripts.
+
+ Creates a list of dictionaries, where each dictionary stores
+ information about a particular script.
+
+ """
examples = []
filesyspath = self.request().serverSidePath()
files = glob(os.path.join(os.path.dirname(filesyspath), "*.psp"))
@@ -30,4 +35,5 @@
if self.application().hasContext('Documentation'):
filename = 'Documentation/WebKit.html'
if os.path.exists(filename):
- self.menuItem('Local WebKit docs', self.request().servletPath() + '/' + filename)
+ self.menuItem('Local WebKit docs',
+ self.request().servletPath() + '/' + filename)
Modified: Webware/trunk/PSP/Generators.py
==============================================================================
--- Webware/trunk/PSP/Generators.py (original)
+++ Webware/trunk/PSP/Generators.py Thu Feb 7 19:54:12 2008
@@ -1,10 +1,12 @@
"""Generate Python code from PSP templates.
- This module holds the classes that generate the Python code resulting from the PSP template file.
- As the parser encounters PSP elements, it creates a new Generator object for that type of element.
- Each of these elements is put into a list maintained by the ParseEventHandler object. When it comes
- time to output the Source Code, each generator is called in turn to create it's source.
+ This module holds the classes that generate the Python code resulting
+ from the PSP template file. As the parser encounters PSP elements,
+ it creates a new Generator object for that type of element.
+ Each of these elements is put into a list maintained by the
+ ParseEventHandler object. When it comes time to output the source code,
+ each generator is called in turn to create it's source.
(c) Copyright by Jay Love, 2000 (mailto:jsliv@...)
Modified: Webware/trunk/PSP/PSPParser.py
==============================================================================
--- Webware/trunk/PSP/PSPParser.py (original)
+++ Webware/trunk/PSP/PSPParser.py Thu Feb 7 19:54:12 2008
@@ -318,7 +318,8 @@
handler.setTemplateInfo(self.tmplStart, self.tmplStop)
handler.handleMethod(start, stop, attrs)
start = stop
- stop = reader.skipUntil(CLOSE_METHOD_2) #skip past the close marker, return the point before the close marker
+ # skip past the close marker, return the point before the close marker
+ stop = reader.skipUntil(CLOSE_METHOD_2)
handler.handleMethodEnd(start, stop, attrs)
return 1
return 0
Modified: Webware/trunk/TaskKit/Task.py
==============================================================================
--- Webware/trunk/TaskKit/Task.py (original)
+++ Webware/trunk/TaskKit/Task.py Thu Feb 7 19:54:12 2008
@@ -1,5 +1,6 @@
from MiscUtils import AbstractError
+
class Task:
"""Abstract base class from which you have to derive your own tasks."""
Modified: Webware/trunk/bin/MakeAppWorkDir.py
==============================================================================
--- Webware/trunk/bin/MakeAppWorkDir.py (original)
+++ Webware/trunk/bin/MakeAppWorkDir.py Thu Feb 7 19:54:12 2008
@@ -335,7 +335,7 @@
except:
self.msg("\tWarning: The ownership could not be changed.")
else:
- for (dir, dirs, files) in os.walk(self._workDir):
+ for dir, dirs, files in os.walk(self._workDir):
for file in dirs + files:
path = os.path.join(dir, file)
os.chown(path, uid, gid)
Modified: Webware/trunk/bin/pystats.py
==============================================================================
--- Webware/trunk/bin/pystats.py (original)
+++ Webware/trunk/bin/pystats.py Thu Feb 7 19:54:12 2008
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-"""
-pystats.py
+"""pystats.py
+
Reports stats for various aspects of Python source including:
@@ -11,7 +11,8 @@
# of methods/functions
# of classes
-You can think of this as a UNIX "wc" on steroids (that also works on any Python platform).
+You can think of this as a UNIX "wc" on steroids (that also works on any
+Python platform).
USAGE
@@ -26,9 +27,12 @@
CAVEATS
-PyStats doesn't count classes, functions and methods perfectly. It can be fooled by multiline strings and such. But it's close enough to get an idea and the odd ball cases don't happen frequently.
+PyStats doesn't count classes, functions and methods perfectly. It can be
+fooled by multiline strings and such. But it's close enough to get an idea
+and the odd ball cases don't happen frequently.
-Webware includes some third party Python files, which you may or may not believe should be counted as part of the stats.
+Webware includes some third party Python files, which you may or may not
+believe should be counted as part of the stats.
Number of bytes is a little low on Windows where \r\n is counted just as \n.
@@ -48,13 +52,16 @@
Option for writing HTML results.
-Both this utility and checksrc.py are in need of a ReadPyLines() function that would be like readlines() but would bastardize the contents of multiline strings to avoid misunderstandings concerning tabs, spaces, def's, class's etc. See tabnanny in Py 2.0, it might have the answer or even reusable code.
+Both this utility and checksrc.py are in need of a ReadPyLines() function that
+would be like readlines() but would bastardize the contents of multiline strings
+to avoid misunderstandings concerning tabs, spaces, def's, class's etc.
+See tabnanny in Py 2.0, it might have the answer or even reusable code.
-Some of our code is in common with checksrc.py. One more similar program and it might be time for an abstract class for these guys.
+Some of our code is in common with checksrc.py. One more similar program and it
+might be time for an abstract class for these guys.
Provide command line option to change extensions.
-Py 2.0: Use dict.setdefault() & +=
"""
@@ -64,17 +71,17 @@
class Stats(UserDict):
- statNames = 'files bytes lines funcs classes'.split()
+ _statNames = 'files bytes lines funcs classes'.split()
def __init__(self, dict=None):
UserDict.__init__(self, dict)
if dict is None:
- for name in self.statNames:
+ for name in self._statNames:
self[name] = 0
def __add__(self, stats):
result = self.__class__()
- for name in self.statNames:
+ for name in self._statNames:
result[name] = self[name] + stats[name]
return result
@@ -88,15 +95,15 @@
return self.__class__(self.data)
def write(self, file=sys.stdout):
- for name in self.statNames:
+ for name in self._statNames:
file.write('%8d' % self[name])
-def Stats_writeHeaders(nameWidth, file=sys.stdout):
- # This would be a class method in Python >= 2.2: Stats.writeHeaders().
- file.write(' '*nameWidth)
- for name in Stats._statNames:
- file.write('%8s' % name)
- file.write('\n')
+ def writeHeaders(self, nameWidth, file=sys.stdout):
+ # this would be a class method in Python >= 2.2
+ file.write(' ' * nameWidth)
+ for name in self._statNames:
+ file.write('%8s' % name)
+ file.write('\n')
class StatsNode:
@@ -106,9 +113,9 @@
def __init__(self, name):
self._name = name
- self._subNodes = {} # map directory names to StatsNodes
- self._stats = Stats() # stats for files just in this dir (no subdirs)
- self._totalStats = None # stats for all files, recursively in subdirs
+ self._subNodes = {} # map directory names to StatsNodes
+ self._stats = Stats() # stats for files just in this dir (no subdirs)
+ self._totalStats = None # stats for all files, recursively in subdirs
def name(self):
return self._name
@@ -150,7 +157,7 @@
def write(self, file=sys.stdout, recurse=1, indent=0, indenter=' '):
if indent == 0:
- Stats_writeHeaders(25, file)
+ self._stats.writeHeaders(25, file)
spacer = indenter * indent
name = self._name.ljust(25-len(spacer))
file.write(spacer+name)
@@ -178,7 +185,6 @@
self.setExtensions(['.py', '.psp', '.cgi'])
self.setRecurse(1)
self.setShowSummary(0)
- self.setVerbose(0)
## Options ##
@@ -187,7 +193,7 @@
return self._directory
def setDirectory(self, dir):
- """ Sets the directory that checking starts in. """
+ """Set the directory that checking starts in."""
self._directory = dir
def extensions(self):
@@ -200,7 +206,7 @@
return self._recurse
def setRecurse(self, flag):
- """ Sets whether or not to recurse into subdirectories. """
+ """Set whether or not to recurse into subdirectories."""
self._recurse = flag
def showSummary(self):
@@ -209,13 +215,6 @@
def setShowSummary(self, flag):
self._showSummary = flag
- def verbose(self):
- return self._verbose
-
- def setVerbose(self, flag):
- """ Sets whether or not to print extra information during check (such as every directory and file name scanned). """
- self._verbose = flag
-
## Command line use ##
@@ -249,11 +248,6 @@
self.setShowSummary(1)
elif arg == '-S':
self.setShowSummary(0)
- # We don't have any use for a verbose option right now.
- # elif arg == '-v':
- # self.setVerbose(1)
- # elif arg == '-V':
- # self.setVerbose(0)
elif arg[0] == '-':
self.usage()
return 0
|
| Thread | Author | Date |
|---|---|---|
| [Webware-checkins] r7216 - in Webware/trunk: DocSupport MiddleKit/Design MiddleKit/Run MiscUtils PSP PSP/Examples TaskKit bin | <updates@we...> |