summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Kreen2009-02-13 12:21:09 +0000
committerMarko Kreen2009-02-13 13:20:52 +0000
commit096cb8d354890a8f67a0edb74f934ec6f2ffa826 (patch)
treecd454468f1cfb5a4f53556ff9b165754026aaf80
parent5dd59cd49795fdd5c281938c9336c1dc188f5324 (diff)
build system update
- make check target to use pychecker on codebase - configure switch to install user-runnable python scripts without .py extension - reset debian/changelog - deb: drop psycopg1, pg8.0, pg8.1
-rw-r--r--Makefile11
-rw-r--r--config.mak.in1
-rw-r--r--configure.ac12
-rw-r--r--debian/changelog42
-rw-r--r--debian/packages.in2
-rwxr-xr-xmisc/docheck.sh17
-rw-r--r--misc/lint.rc319
-rw-r--r--misc/pychecker.rc223
-rw-r--r--misc/pychecker.strict.rc224
-rwxr-xr-xmisc/run.lint.sh11
-rw-r--r--misc/strip_ext.py15
11 files changed, 835 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 3903121f..7a59ed81 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,11 @@ modules-install: config.mak
test \! -d compat || $(MAKE) -C compat $@ DESTDIR=$(DESTDIR)
python-install: config.mak modules-all
- $(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR)/
+ $(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR)/ --record=tmp_files.lst
+#ifeq ($(STRIP_PY), yes)
+ grep '/bin/[a-z_0-9]*.py' tmp_files.lst \
+ | $(PYTHON) misc/strip_ext.py $(if $(DESTDIR), $(DESTDIR), /)
+#endif
$(MAKE) -C doc DESTDIR=$(DESTDIR) install
python-install python-all: python/skytools/installer_config.py
@@ -93,6 +97,9 @@ configure: configure.ac
tags:
ctags `find python -name '*.py'`
+check:
+ ./misc/docheck.sh
+
.PHONY: all clean distclean install deb debclean tgz tags
-.PHONY: python-all python-clean python-install
+.PHONY: python-all python-clean python-install check
diff --git a/config.mak.in b/config.mak.in
index 66985f9e..78bf8865 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -18,3 +18,4 @@ DESTDIR =
ASCIIDOC = @ASCIIDOC@
XMLTO = @XMLTO@
+extensionless_scripts = @extensionless_scripts@
diff --git a/configure.ac b/configure.ac
index d57c49e9..17e8f698 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,6 +63,18 @@ changequote([, ])dnl
esac
fi
+AC_ARG_ENABLE(extensionless-scripts, AC_HELP_STRING([--enable-extensionless-scripts],[remove .py extension from installed scripts]))
+AC_MSG_CHECKING([if .py should be stripped])
+if test "$enable_extensionless_scripts" = "yes"; then
+ extensionless_scripts=yes
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+AC_SUBST(extensionless_scripts)
+
+
+
dnl check for xmlto, but only if asciidoc is found
if test -n "$ASCIIDOC"; then
AC_CHECK_PROGS(XMLTO, [$XMLTO xmlto])
diff --git a/debian/changelog b/debian/changelog
index de385353..e59427a5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,42 +1,6 @@
-skytools (3.0git-0) unstable; urgency=low
+skytools (3.0a-0) unstable; urgency=low
- * tag the tree as 3.0
+ * dev tree for 3.0
- -- Marko Kreen <[email protected]> Wed, 05 Dec 2007 17:53:05 +0200
-
-skytools (2.1.5) unstable; urgency=low
-
- * New public release.
-
- -- Marko Kreen <[email protected]> Mon, 19 Nov 2007 15:32:41 +0200
-
-skytools (2.1.4) unstable; urgency=low
-
- * Upgrade walmgr, some fixes.
-
- -- Marko Kreen <[email protected]> Fri, 13 Apr 2007 11:08:41 +0300
-
-skytools (2.1.3) unstable; urgency=low
-
- * brown paper bag
-
- -- Marko Kreen <[email protected]> Tue, 10 Apr 2007 11:55:47 +0300
-
-skytools (2.1.2) unstable; urgency=low
-
- * more bugfixes
-
- -- Marko Kreen <[email protected]> Mon, 09 Apr 2007 17:56:35 +0300
-
-skytools (2.1.1) unstable; urgency=low
-
- * bugfixes
-
- -- Marko Kreen <[email protected]> Tue, 03 Apr 2007 15:03:28 +0300
-
-skytools (2.1) unstable; urgency=low
-
- * cleanup
-
- -- Marko Kreen <[email protected]> Fri, 02 Feb 2007 12:38:17 +0200
+ -- Marko Kreen <[email protected]> T, 13 jaan 2009 14:24:17 +0200
diff --git a/debian/packages.in b/debian/packages.in
index cf645e5f..65fba7d7 100644
--- a/debian/packages.in
+++ b/debian/packages.in
@@ -20,7 +20,7 @@ Build-Depends: python-dev, postgresql-server-dev-PGVER
Package: skytools
Architecture: any
-Depends: python-psycopg2 | pythonPYVER-psycopg2 | python-psycopg | pythonPYVER-psycopg, skytools-modules-8.2 | skytools-modules-8.1 | skytools-modules-8.0, []
+Depends: python-psycopg2 | pythonPYVER-psycopg2, skytools-modules-8.4 | skytools-modules-8.3 | skytools-modules-8.2, []
Description: Skype database tools - Python parts
.
londiste - replication
diff --git a/misc/docheck.sh b/misc/docheck.sh
new file mode 100755
index 00000000..f2a27f58
--- /dev/null
+++ b/misc/docheck.sh
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+PYTHONPATH=python:$PYTHONPATH
+export PYTHONPATH
+
+
+for f in \
+python/skytools/*.py \
+python/pgq/*.py \
+python/pgq/cascade/*.py \
+python/londiste/*.py \
+python/*.py \
+scripts/*.py
+do
+ pychecker --config misc/pychecker.rc "$f"
+done
+
diff --git a/misc/lint.rc b/misc/lint.rc
new file mode 100644
index 00000000..36690aa6
--- /dev/null
+++ b/misc/lint.rc
@@ -0,0 +1,319 @@
+# lint Python modules using external checkers.
+#
+# This is the main checker controling the other ones and the reports
+# generation. It is itself both a raw checker and an astng checker in order
+# to:
+# * handle message activation / deactivation at the module level
+# * handle some basic but necessary stats'data (number of classes, methods...)
+#
+[MASTER]
+
+# Specify a configuration file.
+#rcfile=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Profiled execution.
+profile=no
+
+# Add <file or directory> to the black list. It should be a base name, not a
+# path. You may set this option multiple times.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Set the cache size for astng objects.
+cache-size=500
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+
+[MESSAGES CONTROL]
+
+#['metrics', 'design', 'format', 'similarities', 'variables', 'rpython', 'miscellaneous', 'imports', 'basic', 'classes', 'master', 'typecheck', 'exceptions', 'newstyle']
+
+# Enable only checker(s) with the given id(s). This option conflicts with the
+# disable-checker option
+#enable-checker=
+
+# Enable all checker(s) except those with the given id(s). This option
+# conflicts with the enable-checker option
+#disable-checker=design
+
+# Enable all messages in the listed categories.
+#enable-msg-cat=
+
+# Disable all messages in the listed categories.
+#disable-msg-cat=
+
+# Enable the message(s) with the given id(s).
+#enable-msg=
+
+# Disable the message(s) with the given id(s).
+disable-msg=W0142,R0201,W0613,W0622,C0321,W0612,W0614,W0102,W0602,W0603,W0704,W0702,I0001,W0212,W0401,W0141,E1102,W0232,W0703
+
+
+[REPORTS]
+
+# set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html
+output-format=text
+
+# Include message's id in output
+include-ids=no
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells wether to display a full report or only the messages
+reports=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note).You have access to the variables errors warning, statement which
+# respectivly contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (R0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (R0004).
+comment=no
+
+# Enable the report(s) with the given id(s).
+#enable-report=
+
+# Disable the report(s) with the given id(s).
+#disable-report=
+
+
+# try to find bugs in the code using type inference
+#
+[TYPECHECK]
+
+# Tells wether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamicaly set).
+ignored-classes=SQLObject
+
+# When zope mode is activated, consider the acquired-members option to ignore
+# access to some undefined attributes.
+zope=no
+
+# List of members which are usually get through zope's acquisition mecanism and
+# so shouldn't trigger E0201 when accessed (need zope=yes to be considered).
+acquired-members=REQUEST,acl_users,aq_parent
+
+
+# checks for
+# * unused variables / imports
+# * undefined variables
+# * redefinition of variable from builtins or from an outer scope
+# * use of variable before assigment
+#
+[VARIABLES]
+
+# Tells wether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching names used for dummy variables (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+# checks for :
+# * doc strings
+# * modules / classes / functions / methods / arguments / variables name
+# * number of arguments, local variables, branchs, returns and statements in
+# functions, methods
+# * required module attributes
+# * dangerous default values as arguments
+# * redefinition of function / method / class
+# * uses of the global statement
+#
+[BASIC]
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+#no-docstring-rgx=_.*
+no-docstring-rgx=.*
+# FIXME
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct module level names
+#const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$
+const-rgx=.*
+
+# Regular expression which should only match correct class names
+#class-rgx=[A-Za-z_][_a-zA-Z0-9]+$
+class-rgx=.*
+
+# Regular expression which should only match correct function names
+#function-rgx=[a-z_][a-z0-9_]*$
+function-rgx=.*
+
+# Regular expression which should only match correct method names
+#method-rgx=[a-z_][a-z0-9_]*$
+method-rgx=.*
+
+# Regular expression which should only match correct instance attribute names
+#attr-rgx=[a-z_][a-z0-9_]*$
+attr-rgx=.*
+
+# Regular expression which should only match correct argument names
+#argument-rgx=[a-z_][a-z0-9_]*$
+argument-rgx=.*
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]*$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+
+# checks for :
+# * methods without self as first argument
+# * overridden methods signature
+# * access only to existant members via self
+# * attributes not defined in the __init__ method
+# * supported interfaces implementation
+# * unreachable code
+#
+[CLASSES]
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+
+# checks for
+# * external modules dependencies
+# * relative / wildcard imports
+# * cyclic imports
+# * uses of deprecated modules
+#
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report R0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report R0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report R0402 must
+# not be disabled)
+int-import-graph=
+
+
+# checks for sign of poor/misdesign:
+# * number of methods, attributes, local variables...
+# * size, complexity of functions, methods
+#
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=10
+
+# Maximum number of locals for function / method body
+max-locals=20
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=20
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=20
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=1
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=30
+
+
+# checks for similarities and duplicated code. This computation may be
+# memory / CPU intensive, so you should disable it if you experiments some
+# problems.
+#
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+
+# checks for :
+# * unauthorized constructions
+# * strict indentation
+# * line length
+# * use of <> instead of !=
+#
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=200
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+
+# checks for:
+# * warning notes in the code like FIXME, XXX
+# * PEP 263: source code with non ascii character but no encoding declaration
+#
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
diff --git a/misc/pychecker.rc b/misc/pychecker.rc
new file mode 100644
index 00000000..01ee0b74
--- /dev/null
+++ b/misc/pychecker.rc
@@ -0,0 +1,223 @@
+#
+# .pycheckrc file for Skytools
+#
+
+# only warn about files passed on the command line
+only = 1
+
+# the maximum number of warnings to be displayed
+limit = 50
+
+# list of evil C extensions that crash the interpreter
+evil = []
+
+# unused imports
+importUsed = 1
+
+# unused imports from __init__.py
+packageImportUsed = 1
+
+# module imports itself
+reimportSelf = 1
+
+ignoreImportErrors = 0
+
+# reimporting a module
+moduleImportErrors = 1
+
+# module does import and from ... import
+mixImport = 1
+
+# unused local variables, except tuples
+localVariablesUsed = 0
+
+# all unused local variables, including tuples
+unusedLocalTuple = 0
+
+# all unused class data members
+membersUsed = 0
+
+# all unused module variables
+allVariablesUsed = 0
+
+# unused private module variables
+privateVariableUsed = 1
+
+# report each occurrence of global warnings
+reportAllGlobals = 1
+
+# functions called with named arguments (like keywords)
+namedArgs = 0
+
+# Attributes (members) must be defined in __init__()
+onlyCheckInitForMembers = True
+
+# Subclass.__init__() not defined
+initDefinedInSubclass = 0
+
+# Baseclass.__init__() not called
+baseClassInitted = 1
+
+# Subclass needs to override methods that only throw exceptions
+abstractClasses = 1
+
+# Return None from __init__()
+returnNoneFromInit = 1
+
+# unreachable code
+unreachableCode = 0
+
+# a constant is used in a conditional statement
+constantConditions = 1
+
+# 1 is used in a conditional statement (if 1: or while 1:)
+constant1 = 0
+
+# check if iterating over a string
+stringIteration = 1
+
+# check improper use of string.find()
+stringFind = 1
+
+# Calling data members as functions
+callingAttribute = 0
+
+# class attribute does not exist
+classAttrExists = 1
+
+# First argument to methods
+methodArgName = 'self'
+
+# First argument to classmethods
+classmethodArgNames = ['cls', 'klass']
+
+# unused method/function arguments
+argumentsUsed = False
+
+# unused method/function variable arguments
+varArgumentsUsed = 1
+
+# ignore if self is unused in methods
+ignoreSelfUnused = 0
+
+# check if overridden methods have the same signature
+checkOverridenMethods = 1
+
+# check if __special__ methods exist and have the correct signature
+checkSpecialMethods = 1
+
+# check if function/class/method names are reused
+redefiningFunction = 1
+
+# check if using unary positive (+) which is usually meaningless
+unaryPositive = 1
+
+# check if modify (call method) on a parameter that has a default value
+modifyDefaultValue = 1
+
+# check if variables are set to different types
+inconsistentTypes = True
+
+# check if unpacking a non-sequence
+unpackNonSequence = 1
+
+# check if unpacking sequence with the wrong length
+unpackLength = 1
+
+# check if raising or catching bad exceptions
+badExceptions = True
+
+# check if statement appears to have no effect
+noEffect = 1
+
+# check if using (expr % 1), it has no effect on integers and strings
+modulo1 = 1
+
+# check if using (expr is const-literal), doesn't always work on integers and strings
+isLiteral = 1
+
+# check consistent return values
+checkReturnValues = 1
+
+# check if using implict and explicit return values
+checkImplicitReturns = 1
+
+# check that attributes of objects exist
+checkObjectAttrs = 1
+
+# various warnings about incorrect usage of __slots__
+slots = 1
+
+# using properties with classic classes
+classicProperties = 1
+
+# check if __slots__ is empty
+emptySlots = 1
+
+# check if using integer division
+intDivide = 1
+
+# check if local variable shadows a global
+shadows = 1
+
+# check if a variable shadows a builtin
+shadowBuiltins = 0
+
+# check if input() is used
+usesInput = 1
+
+# check if the exec statement is used
+usesExec = True
+
+# ignore warnings from files under standard library
+ignoreStandardLibrary = 0
+
+# ignore warnings from the list of modules
+blacklist = ['Tkinter', 'wxPython', 'gtk', 'GTK', 'GDK']
+
+# ignore global variables not used if name is one of these values
+variablesToIgnore = ['__version__', '__warningregistry__', '__all__', '__credits__', '__test__', '__author__', '__email__', '__revision__', '__id__', '__copyright__', '__license__', '__date__']
+
+# ignore unused locals/arguments if name is one of these values
+unusedNames = ['_', 'empty', 'unused', 'dummy']
+
+# ignore use of deprecated modules/functions
+deprecated = False
+
+# maximum lines in a function
+maxLines = 200
+
+# maximum branches in a function
+maxBranches = 30
+
+# maximum returns in a function
+maxReturns = 20
+
+# maximum # of arguments to a function
+maxArgs = 10
+
+# maximum # of locals in a function
+maxLocals = 30
+
+# maximum # of identifier references (Law of Demeter)
+maxReferences = 5
+
+# no module doc strings
+noDocModule = True
+
+# no class doc strings
+noDocClass = True
+
+# no function/method doc strings
+noDocFunc = False
+
+
+# print internal checker parse structures
+printParse = 0
+
+# turn on debugging for checker
+debug = 0
+
+# turn off all output except warnings
+quiet = 1
+
diff --git a/misc/pychecker.strict.rc b/misc/pychecker.strict.rc
new file mode 100644
index 00000000..3e0843ce
--- /dev/null
+++ b/misc/pychecker.strict.rc
@@ -0,0 +1,224 @@
+#
+# .pycheckrc file for Skytools
+#
+
+# only warn about files passed on the command line
+only = 1
+
+# the maximum number of warnings to be displayed
+limit = 50
+
+# list of evil C extensions that crash the interpreter
+evil = []
+
+# unused imports
+importUsed = 1
+
+# unused imports from __init__.py
+packageImportUsed = 1
+
+# module imports itself
+reimportSelf = 1
+
+ignoreImportErrors = 0
+
+# reimporting a module
+moduleImportErrors = 1
+
+# module does import and from ... import
+mixImport = 0
+
+# unused local variables, except tuples
+localVariablesUsed = 1
+
+# all unused local variables, including tuples
+unusedLocalTuple = 0
+
+# all unused class data members
+membersUsed = 0
+
+# all unused module variables
+allVariablesUsed = 1
+
+# unused private module variables
+privateVariableUsed = 1
+
+# report each occurrence of global warnings
+reportAllGlobals = 1
+
+# functions called with named arguments (like keywords)
+namedArgs = 0
+
+# Attributes (members) must be defined in __init__()
+onlyCheckInitForMembers = True
+
+# Subclass.__init__() not defined
+initDefinedInSubclass = 0
+
+# Baseclass.__init__() not called
+baseClassInitted = 1
+
+# Subclass needs to override methods that only throw exceptions
+abstractClasses = 1
+
+# Return None from __init__()
+returnNoneFromInit = 1
+
+# unreachable code
+unreachableCode = 0
+
+# a constant is used in a conditional statement
+constantConditions = 1
+
+# 1 is used in a conditional statement (if 1: or while 1:)
+constant1 = 0
+
+# check if iterating over a string
+stringIteration = 1
+
+# check improper use of string.find()
+stringFind = 1
+
+# Calling data members as functions
+callingAttribute = 0
+
+# class attribute does not exist
+classAttrExists = 1
+
+# First argument to methods
+methodArgName = 'self'
+
+# First argument to classmethods
+classmethodArgNames = ['cls', 'klass']
+
+# unused method/function arguments
+argumentsUsed = False
+
+# unused method/function variable arguments
+varArgumentsUsed = 1
+
+# ignore if self is unused in methods
+ignoreSelfUnused = 0
+
+# check if overridden methods have the same signature
+checkOverridenMethods = 1
+
+# check if __special__ methods exist and have the correct signature
+checkSpecialMethods = 1
+
+# check if function/class/method names are reused
+redefiningFunction = 1
+
+# check if using unary positive (+) which is usually meaningless
+unaryPositive = 1
+
+# check if modify (call method) on a parameter that has a default value
+modifyDefaultValue = 1
+
+# check if variables are set to different types
+inconsistentTypes = True
+
+# check if unpacking a non-sequence
+unpackNonSequence = 1
+
+# check if unpacking sequence with the wrong length
+unpackLength = 1
+
+# check if raising or catching bad exceptions
+badExceptions = False
+# DBScript wants to catch KeyboardException + SystemExit
+
+# check if statement appears to have no effect
+noEffect = 1
+
+# check if using (expr % 1), it has no effect on integers and strings
+modulo1 = 1
+
+# check if using (expr is const-literal), doesn't always work on integers and strings
+isLiteral = 1
+
+# check consistent return values
+checkReturnValues = 1
+
+# check if using implict and explicit return values
+checkImplicitReturns = 1
+
+# check that attributes of objects exist
+checkObjectAttrs = 1
+
+# various warnings about incorrect usage of __slots__
+slots = 1
+
+# using properties with classic classes
+classicProperties = 1
+
+# check if __slots__ is empty
+emptySlots = 1
+
+# check if using integer division
+intDivide = 1
+
+# check if local variable shadows a global
+shadows = 1
+
+# check if a variable shadows a builtin
+shadowBuiltins = 1
+
+# check if input() is used
+usesInput = 1
+
+# check if the exec statement is used
+usesExec = True
+
+# ignore warnings from files under standard library
+ignoreStandardLibrary = 0
+
+# ignore warnings from the list of modules
+blacklist = ['Tkinter', 'wxPython', 'gtk', 'GTK', 'GDK']
+
+# ignore global variables not used if name is one of these values
+variablesToIgnore = ['__version__', '__warningregistry__', '__all__', '__credits__', '__test__', '__author__', '__email__', '__revision__', '__id__', '__copyright__', '__license__', '__date__']
+
+# ignore unused locals/arguments if name is one of these values
+unusedNames = ['_', 'empty', 'unused', 'dummy']
+
+# ignore use of deprecated modules/functions
+deprecated = False
+
+# maximum lines in a function
+maxLines = 100
+
+# maximum branches in a function
+maxBranches = 20
+
+# maximum returns in a function
+maxReturns = 10
+
+# maximum # of arguments to a function
+maxArgs = 10
+
+# maximum # of locals in a function
+maxLocals = 20
+
+# maximum # of identifier references (Law of Demeter)
+maxReferences = 5
+
+# no module doc strings
+noDocModule = False
+
+# no class doc strings
+noDocClass = False
+
+# no function/method doc strings
+noDocFunc = False
+
+
+# print internal checker parse structures
+printParse = 0
+
+# turn on debugging for checker
+debug = 0
+
+# turn off all output except warnings
+quiet = 1
+
diff --git a/misc/run.lint.sh b/misc/run.lint.sh
new file mode 100755
index 00000000..6283773a
--- /dev/null
+++ b/misc/run.lint.sh
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+bdir=`echo build/lib.*`
+#cd python
+#export PYTHONPATH=.:../$bdir:$PYTHONPATH
+#echo $PYTHONPATH
+
+cd $bdir
+export PYTHONPATH=.:$PYTHONPATH
+pylint -i yes --rcfile=../../misc/lint.rc skytools
+
diff --git a/misc/strip_ext.py b/misc/strip_ext.py
new file mode 100644
index 00000000..240cc04b
--- /dev/null
+++ b/misc/strip_ext.py
@@ -0,0 +1,15 @@
+#! /usr/bin/env python
+
+import sys, os, os.path
+
+while 1:
+ fn = sys.stdin.readline().strip()
+ if not fn:
+ break
+ full1 = os.path.join(sys.argv[1], fn)
+ full2 = os.path.splitext(full1)[0]
+ if full1 == full2:
+ continue
+ print full1, full2
+ os.rename(full1, full2)
+