[svn r57540] merge changes from release branch back
[svn merge -r 57430:HEAD ../release/0.9.x/ .] * cmdline script organisation * execnet windows fixes * documentation updates * test skips also regen setup.py --HG-- branch : trunk
This commit is contained in:
parent
c0d524139e
commit
a999dc8472
17
CHANGELOG
17
CHANGELOG
|
@ -1,20 +1,29 @@
|
||||||
$Id: CHANGELOG 57429 2008-08-18 15:08:39Z hpk $
|
$Id: CHANGELOG 57540 2008-08-21 10:18:58Z hpk $
|
||||||
|
|
||||||
Changes between 0.9.1 and 0.9.2
|
Changes between 0.9.1 and 0.9.2
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
* refined installation and metadata, created new setup.py,
|
* refined installation and metadata, created new setup.py,
|
||||||
now based on setuptools/ez_setup (by flipping a bit you
|
now based on setuptools/ez_setup (thanks to Ralf Schmitt
|
||||||
can use distutils).
|
for his support).
|
||||||
|
|
||||||
* improved the way of making py.* scripts available in
|
* improved the way of making py.* scripts available in
|
||||||
windows environments, they are now added to the
|
windows environments, they are now added to the
|
||||||
Scripts directory as ".cmd" files.
|
Scripts directory as ".cmd" files.
|
||||||
|
|
||||||
* improved py.execnet bootstrapping on windows
|
* py.path.svnwc.status() now is more complete and
|
||||||
|
uses xml output from the 'svn' command if available
|
||||||
|
(Guido Wesdorp)
|
||||||
|
|
||||||
|
* fix for py.path.svn* to work with svn 1.5
|
||||||
|
(Chris Lamb)
|
||||||
|
|
||||||
|
* fix path.relto(otherpath) method on windows to
|
||||||
|
use normcase for checking if a path is relative.
|
||||||
|
|
||||||
* py.test's traceback is better parseable from editors
|
* py.test's traceback is better parseable from editors
|
||||||
(follows the filenames:LINENO: MSG convention)
|
(follows the filenames:LINENO: MSG convention)
|
||||||
|
(thanks to Osmo Salomaa)
|
||||||
|
|
||||||
* fix to javascript-generation, "py.test --runbrowser"
|
* fix to javascript-generation, "py.test --runbrowser"
|
||||||
should work more reliably now
|
should work more reliably now
|
||||||
|
|
16
MANIFEST
16
MANIFEST
|
@ -61,13 +61,20 @@ py/apigen/tracer/testing/test_docgen.py
|
||||||
py/apigen/tracer/testing/test_model.py
|
py/apigen/tracer/testing/test_model.py
|
||||||
py/apigen/tracer/testing/test_package.py
|
py/apigen/tracer/testing/test_package.py
|
||||||
py/apigen/tracer/tracer.py
|
py/apigen/tracer/tracer.py
|
||||||
|
py/bin/_docgen.py
|
||||||
py/bin/_findpy.py
|
py/bin/_findpy.py
|
||||||
|
py/bin/_genscripts.py
|
||||||
py/bin/py.cleanup
|
py/bin/py.cleanup
|
||||||
py/bin/py.countloc
|
py/bin/py.countloc
|
||||||
py/bin/py.lookup
|
py/bin/py.lookup
|
||||||
py/bin/py.rest
|
py/bin/py.rest
|
||||||
py/bin/py.test
|
py/bin/py.test
|
||||||
py/bin/py.which
|
py/bin/py.which
|
||||||
|
py/bin/win32/py.cleanup.cmd
|
||||||
|
py/bin/win32/py.countloc.cmd
|
||||||
|
py/bin/win32/py.lookup.cmd
|
||||||
|
py/bin/win32/py.rest.cmd
|
||||||
|
py/bin/win32/py.test.cmd
|
||||||
py/builtin/__init__.py
|
py/builtin/__init__.py
|
||||||
py/builtin/enumerate.py
|
py/builtin/enumerate.py
|
||||||
py/builtin/exception.py
|
py/builtin/exception.py
|
||||||
|
@ -100,6 +107,14 @@ py/c-extension/greenlet/test_generator_nested.py
|
||||||
py/c-extension/greenlet/test_greenlet.py
|
py/c-extension/greenlet/test_greenlet.py
|
||||||
py/c-extension/greenlet/test_remote.py
|
py/c-extension/greenlet/test_remote.py
|
||||||
py/c-extension/greenlet/test_throw.py
|
py/c-extension/greenlet/test_throw.py
|
||||||
|
py/cmdline/__init__.py
|
||||||
|
py/cmdline/pycleanup.py
|
||||||
|
py/cmdline/pycountloc.py
|
||||||
|
py/cmdline/pylookup.py
|
||||||
|
py/cmdline/pyrest.py
|
||||||
|
py/cmdline/pytest.py
|
||||||
|
py/cmdline/testing/__init__.py
|
||||||
|
py/cmdline/testing/test_generic.py
|
||||||
py/code/__init__.py
|
py/code/__init__.py
|
||||||
py/code/code.py
|
py/code/code.py
|
||||||
py/code/excinfo.py
|
py/code/excinfo.py
|
||||||
|
@ -419,4 +434,5 @@ py/xmlobj/testing/test_html.py
|
||||||
py/xmlobj/testing/test_xml.py
|
py/xmlobj/testing/test_xml.py
|
||||||
py/xmlobj/visit.py
|
py/xmlobj/visit.py
|
||||||
py/xmlobj/xml.py
|
py/xmlobj/xml.py
|
||||||
|
setup.cfg
|
||||||
setup.py
|
setup.py
|
37
_findpy.py
37
_findpy.py
|
@ -1,37 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
#
|
|
||||||
# find and import a version of 'py'
|
|
||||||
#
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from os.path import dirname as opd, exists, join, basename, abspath
|
|
||||||
|
|
||||||
def searchpy(current):
|
|
||||||
while 1:
|
|
||||||
last = current
|
|
||||||
initpy = join(current, '__init__.py')
|
|
||||||
if not exists(initpy):
|
|
||||||
pydir = join(current, 'py')
|
|
||||||
# recognize py-package and ensure it is importable
|
|
||||||
if exists(pydir) and exists(join(pydir, '__init__.py')):
|
|
||||||
#for p in sys.path:
|
|
||||||
# if p == current:
|
|
||||||
# return True
|
|
||||||
if current != sys.path[0]: # if we are already first, then ok
|
|
||||||
print >>sys.stderr, "inserting into sys.path:", current
|
|
||||||
sys.path.insert(0, current)
|
|
||||||
return True
|
|
||||||
current = opd(current)
|
|
||||||
if last == current:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not searchpy(abspath(os.curdir)):
|
|
||||||
if not searchpy(opd(abspath(sys.argv[0]))):
|
|
||||||
if not searchpy(opd(__file__)):
|
|
||||||
pass # let's hope it is just on sys.path
|
|
||||||
|
|
||||||
import py
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
print "py lib is at", py.__file__
|
|
|
@ -16,6 +16,7 @@ copyrighted by one or more of the following people and organizations:
|
||||||
Contributors include::
|
Contributors include::
|
||||||
|
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
|
Chris Lamb
|
||||||
Harald Armin Massa
|
Harald Armin Massa
|
||||||
Ralf Schmitt
|
Ralf Schmitt
|
||||||
Ian Bicking
|
Ian Bicking
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
the py lib is a development support library featuring
|
The py lib is a development support library featuring these tools and APIs:
|
||||||
py.test, ad-hoc distributed execution, micro-threads
|
|
||||||
and svn abstractions.
|
- `py.test`_: cross-project testing tool with many advanced features
|
||||||
|
- `py.execnet`_: ad-hoc code distribution to SSH, Socket and local sub processes
|
||||||
|
- `py.magic.greenlet`_: micro-threads on standard CPython ("stackless-light") and PyPy
|
||||||
|
- `py.path`_: path abstractions over local and subversion files
|
||||||
|
- `py.code`_: dynamic code compile and traceback printing support
|
||||||
|
|
||||||
|
The py lib and its tools should work well on Linux, Win32,
|
||||||
|
OSX, Python versions 2.3-2.6. For questions please go to
|
||||||
|
http://pylib.org/contact.html
|
||||||
|
|
||||||
|
.. _`py.test`: http://pylib.org/test.html
|
||||||
|
.. _`py.execnet`: http://pylib.org/execnet.html
|
||||||
|
.. _`py.magic.greenlet`: http://pylib.org/greenlet.html
|
||||||
|
.. _`py.path`: http://pylib.org/path.html
|
||||||
|
.. _`py.code`: http://pylib.org/code.html
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from initpkg import initpkg
|
from initpkg import initpkg
|
||||||
|
|
||||||
|
@ -11,18 +26,18 @@ version = "1.0.0a1"
|
||||||
|
|
||||||
initpkg(__name__,
|
initpkg(__name__,
|
||||||
description = "pylib and py.test: agile development and test support library",
|
description = "pylib and py.test: agile development and test support library",
|
||||||
revision = int('$LastChangedRevision: 57529 $'.split(':')[1][:-1]),
|
revision = int('$LastChangedRevision: 57540 $'.split(':')[1][:-1]),
|
||||||
lastchangedate = '$LastChangedDate: 2008-08-21 09:48:44 +0200 (Thu, 21 Aug 2008) $',
|
lastchangedate = '$LastChangedDate: 2008-08-21 12:18:58 +0200 (Thu, 21 Aug 2008) $',
|
||||||
version = version,
|
version = version,
|
||||||
url = "http://pylib.org",
|
url = "http://pylib.org",
|
||||||
download_url = "http://pypi.python.org/pypi?:action=display&name=py",
|
download_url = "http://codespeak.net/py/0.9.2/download.html",
|
||||||
license = "MIT license",
|
license = "MIT license",
|
||||||
platforms = ['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms = ['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
author = "holger krekel, Guido Wesdorp, Carl Friedrich Bolz, Armin Rigo, Maciej Fijalkowski & others",
|
author = "holger krekel, Guido Wesdorp, Carl Friedrich Bolz, Armin Rigo, Maciej Fijalkowski & others",
|
||||||
author_email = "holger at merlinux.eu, py-dev at codespeak.net",
|
author_email = "holger at merlinux.eu, py-dev at codespeak.net",
|
||||||
long_description = globals()['__doc__'],
|
long_description = globals()['__doc__'],
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
"Development Status :: 4 - Beta",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
"Operating System :: POSIX",
|
"Operating System :: POSIX",
|
||||||
|
@ -38,6 +53,13 @@ initpkg(__name__,
|
||||||
|
|
||||||
# EXPORTED API
|
# EXPORTED API
|
||||||
exportdefs = {
|
exportdefs = {
|
||||||
|
# py lib cmdline tools
|
||||||
|
'cmdline.pytest' : ('./cmdline/pytest.py', 'main',),
|
||||||
|
'cmdline.pyrest' : ('./cmdline/pyrest.py', 'main',),
|
||||||
|
'cmdline.pylookup' : ('./cmdline/pylookup.py', 'main',),
|
||||||
|
'cmdline.pycountloc' : ('./cmdline/pycountloc.py', 'main',),
|
||||||
|
'cmdline.pycleanup' : ('./cmdline/pycleanup.py', 'main',),
|
||||||
|
|
||||||
# helpers for use from test functions or collectors
|
# helpers for use from test functions or collectors
|
||||||
'test.__doc__' : ('./test/__init__.py', '__doc__'),
|
'test.__doc__' : ('./test/__init__.py', '__doc__'),
|
||||||
'test.raises' : ('./test/outcome.py', 'raises'),
|
'test.raises' : ('./test/outcome.py', 'raises'),
|
||||||
|
|
|
@ -21,8 +21,21 @@ def pkg_to_dict(module):
|
||||||
for key, value in defs.iteritems():
|
for key, value in defs.iteritems():
|
||||||
chain = key.split('.')
|
chain = key.split('.')
|
||||||
base = module
|
base = module
|
||||||
for elem in chain:
|
# XXX generalize this:
|
||||||
base = getattr(base, elem)
|
# a bit of special casing for greenlets which are
|
||||||
|
# not available on all the platforms that python/py
|
||||||
|
# lib runs
|
||||||
|
try:
|
||||||
|
for elem in chain:
|
||||||
|
base = getattr(base, elem)
|
||||||
|
except RuntimeError, exc:
|
||||||
|
if elem == "greenlet":
|
||||||
|
print exc.__class__.__name__, exc
|
||||||
|
print "Greenlets not supported on this platform. Skipping apigen doc for this module"
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
if value[1] == '*':
|
if value[1] == '*':
|
||||||
d.update(get_star_import_tree(base, key))
|
d.update(get_star_import_tree(base, key))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
""" quick tool to get documentation + apigen docs generated
|
||||||
|
|
||||||
|
given a certain targetpath, apigen docs will be placed in 'apigen',
|
||||||
|
|
||||||
|
user can choose to only build either docs or apigen docs: in this case,
|
||||||
|
the navigation bar will be adjusted
|
||||||
|
"""
|
||||||
|
|
||||||
|
from _findpy import py
|
||||||
|
pypath = py.__pkg__.getpath()
|
||||||
|
print "using pypath", pypath
|
||||||
|
import os
|
||||||
|
|
||||||
|
def run_tests(path, envvars='', args=''):
|
||||||
|
pytestpath = pypath.join('bin/py.test')
|
||||||
|
cmd = ('PYTHONPATH="%s" %s python "%s" %s "%s"' %
|
||||||
|
(pypath.dirpath(), envvars, pytestpath, args, path))
|
||||||
|
print cmd
|
||||||
|
errno = os.system(cmd)
|
||||||
|
assert not errno
|
||||||
|
|
||||||
|
def build_apigen_docs(targetpath, testargs=''):
|
||||||
|
run_tests(pypath,
|
||||||
|
'APIGEN_TARGET="%s/apigen" APIGEN_DOCRELPATH="../"' % (
|
||||||
|
targetpath,),
|
||||||
|
'%s --apigen="%s/apigen/apigen.py"' % (testargs, pypath))
|
||||||
|
|
||||||
|
def build_docs(targetpath, testargs):
|
||||||
|
docpath = pypath.join('doc')
|
||||||
|
run_tests(docpath, '',
|
||||||
|
testargs + ' --forcegen --apigen="%s/apigen/apigen.py"' % (pypath,))
|
||||||
|
docpath.copy(targetpath)
|
||||||
|
|
||||||
|
def build_nav(targetpath, docs=True, api=True):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def build(targetpath, docs=True, api=True, testargs=''):
|
||||||
|
targetpath.ensure(dir=True)
|
||||||
|
if docs:
|
||||||
|
print 'building docs'
|
||||||
|
build_docs(targetpath, testargs)
|
||||||
|
if api:
|
||||||
|
print 'building api'
|
||||||
|
build_apigen_docs(targetpath, testargs)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) == 1:
|
||||||
|
print 'usage: %s <targetdir> [options]'
|
||||||
|
print
|
||||||
|
print ' targetdir: a path to a directory (created if it doesn\'t'
|
||||||
|
print ' exist) where the docs are put'
|
||||||
|
print ' options: options passed to py.test when running the tests'
|
||||||
|
sys.exit(1)
|
||||||
|
targetpath = py.path.local(sys.argv[1])
|
||||||
|
args = ' '.join(sys.argv[2:])
|
||||||
|
build(targetpath, True, True, args)
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
from _findpy import py
|
||||||
|
|
||||||
|
mydir = py.magic.autopath().dirpath()
|
||||||
|
|
||||||
|
def getbasename(name):
|
||||||
|
assert name[:2] == "py"
|
||||||
|
return "py." + name[2:]
|
||||||
|
|
||||||
|
def genscript_unix(name):
|
||||||
|
basename = getbasename(name)
|
||||||
|
path = mydir.join(basename)
|
||||||
|
path.write(py.code.Source("""
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from _findpy import py
|
||||||
|
py.cmdline.%s()
|
||||||
|
""" % name).strip())
|
||||||
|
path.chmod(0755)
|
||||||
|
|
||||||
|
def genscript_windows(name):
|
||||||
|
basename = getbasename(name)
|
||||||
|
winbasename = basename + ".cmd"
|
||||||
|
path = mydir.join("win32").join(winbasename)
|
||||||
|
path.write(py.code.Source("""
|
||||||
|
@echo off
|
||||||
|
python "%%~dp0\..\%s" %%*
|
||||||
|
""" % (basename)).strip())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for name in dir(py.cmdline):
|
||||||
|
if name[0] != "_":
|
||||||
|
genscript_unix(name)
|
||||||
|
genscript_windows(name)
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,3 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
from _findpy import py
|
||||||
"""\
|
py.cmdline.pycleanup()
|
||||||
py.cleanup [PATH]
|
|
||||||
|
|
||||||
Delete pyc file recursively, starting from PATH (which defaults to the current
|
|
||||||
working directory). Don't follow links and don't recurse into directories with
|
|
||||||
a ".".
|
|
||||||
"""
|
|
||||||
from _findpy import py
|
|
||||||
import py
|
|
||||||
|
|
||||||
parser = py.compat.optparse.OptionParser(usage=__doc__)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
if not args:
|
|
||||||
args = ["."]
|
|
||||||
for arg in args:
|
|
||||||
path = py.path.local(arg)
|
|
||||||
print "cleaning path", path
|
|
||||||
for x in path.visit('*.pyc', lambda x: x.check(dotfile=0, link=0)):
|
|
||||||
x.remove()
|
|
|
@ -1,23 +1,3 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
from _findpy import py
|
||||||
# hands on script to compute the non-empty Lines of Code
|
py.cmdline.pycountloc()
|
||||||
# for tests and non-test code
|
|
||||||
|
|
||||||
"""\
|
|
||||||
py.countloc [PATHS]
|
|
||||||
|
|
||||||
Count (non-empty) lines of python code and number of python files recursively
|
|
||||||
starting from a list of paths given on the command line (starting from the
|
|
||||||
current working directory). Distinguish between test files and normal ones and
|
|
||||||
report them separately.
|
|
||||||
"""
|
|
||||||
from _findpy import py
|
|
||||||
import py
|
|
||||||
from py.compat import optparse
|
|
||||||
from py.__.misc.cmdline.countloc import countloc
|
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage=__doc__)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
countloc(args)
|
|
|
@ -1,79 +1,3 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""\
|
|
||||||
py.lookup SEARCH_STRING [options]
|
|
||||||
|
|
||||||
Looks recursively at Python files for a SEARCH_STRING, starting from the
|
|
||||||
present working directory. Prints the line, with the filename and line-number
|
|
||||||
prepended."""
|
|
||||||
|
|
||||||
import sys, os
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
|
||||||
from _findpy import py
|
from _findpy import py
|
||||||
try:
|
py.cmdline.pylookup()
|
||||||
from py.__.io.terminalwriter import ansi_print, terminal_width
|
|
||||||
except ImportError:
|
|
||||||
from py.__.misc.terminal_helper import ansi_print, terminal_width
|
|
||||||
import re
|
|
||||||
|
|
||||||
curdir = py.path.local()
|
|
||||||
def rec(p):
|
|
||||||
return p.check(dotfile=0)
|
|
||||||
|
|
||||||
optparse = py.compat.optparse
|
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage=__doc__)
|
|
||||||
parser.add_option("-i", "--ignore-case", action="store_true", dest="ignorecase",
|
|
||||||
help="ignore case distinctions")
|
|
||||||
parser.add_option("-C", "--context", action="store", type="int", dest="context",
|
|
||||||
default=0, help="How many lines of output to show")
|
|
||||||
|
|
||||||
def find_indexes(search_line, string):
|
|
||||||
indexes = []
|
|
||||||
before = 0
|
|
||||||
while 1:
|
|
||||||
i = search_line.find(string, before)
|
|
||||||
if i == -1:
|
|
||||||
break
|
|
||||||
indexes.append(i)
|
|
||||||
before = i + len(string)
|
|
||||||
return indexes
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
string = args[0]
|
|
||||||
if options.ignorecase:
|
|
||||||
string = string.lower()
|
|
||||||
for x in curdir.visit('*.py', rec):
|
|
||||||
try:
|
|
||||||
s = x.read()
|
|
||||||
except py.error.ENOENT:
|
|
||||||
pass # whatever, probably broken link (ie emacs lock)
|
|
||||||
searchs = s
|
|
||||||
if options.ignorecase:
|
|
||||||
searchs = s.lower()
|
|
||||||
if s.find(string) != -1:
|
|
||||||
lines = s.splitlines()
|
|
||||||
if options.ignorecase:
|
|
||||||
searchlines = s.lower().splitlines()
|
|
||||||
else:
|
|
||||||
searchlines = lines
|
|
||||||
for i, (line, searchline) in enumerate(zip(lines, searchlines)):
|
|
||||||
indexes = find_indexes(searchline, string)
|
|
||||||
if not indexes:
|
|
||||||
continue
|
|
||||||
if not options.context:
|
|
||||||
sys.stdout.write("%s:%d: " %(x.relto(curdir), i+1))
|
|
||||||
last_index = 0
|
|
||||||
for index in indexes:
|
|
||||||
sys.stdout.write(line[last_index: index])
|
|
||||||
ansi_print(line[index: index+len(string)],
|
|
||||||
file=sys.stdout, esc=31, newline=False)
|
|
||||||
last_index = index + len(string)
|
|
||||||
sys.stdout.write(line[last_index:] + "\n")
|
|
||||||
else:
|
|
||||||
context = (options.context)/2
|
|
||||||
for count in range(max(0, i-context), min(len(lines) - 1, i+context+1)):
|
|
||||||
print "%s:%d: %s" %(x.relto(curdir), count+1, lines[count].rstrip())
|
|
||||||
print "-" * terminal_width
|
|
|
@ -1,79 +1,3 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""
|
|
||||||
invoke
|
|
||||||
|
|
||||||
py.rest filename1.txt directory
|
|
||||||
|
|
||||||
to generate html files from ReST.
|
|
||||||
|
|
||||||
It is also possible to generate pdf files using the --topdf option.
|
|
||||||
|
|
||||||
http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os, sys
|
|
||||||
from _findpy import py
|
from _findpy import py
|
||||||
from py.__.misc import rest
|
py.cmdline.pyrest()
|
||||||
from py.__.rest import directive
|
|
||||||
from py.__.rest.latex import process_rest_file, process_configfile
|
|
||||||
|
|
||||||
|
|
||||||
if hasattr(sys.stdout, 'fileno') and os.isatty(sys.stdout.fileno()):
|
|
||||||
def log(msg):
|
|
||||||
print msg
|
|
||||||
else:
|
|
||||||
def log(msg):
|
|
||||||
pass
|
|
||||||
|
|
||||||
optparse = py.compat.optparse
|
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage=__doc__)
|
|
||||||
parser.add_option("--topdf", action="store_true", dest="topdf", default=False,
|
|
||||||
help="generate pdf files")
|
|
||||||
parser.add_option("--stylesheet", dest="stylesheet", default=None,
|
|
||||||
help="use specified latex style sheet")
|
|
||||||
parser.add_option("--debug", action="store_true", dest="debug",
|
|
||||||
default=False,
|
|
||||||
help="print debug output and don't delete files")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
if len(args) == 0:
|
|
||||||
filenames = [py.path.svnwc()]
|
|
||||||
else:
|
|
||||||
filenames = [py.path.svnwc(x) for x in args]
|
|
||||||
|
|
||||||
if options.topdf:
|
|
||||||
directive.set_backend_and_register_directives("latex")
|
|
||||||
|
|
||||||
for p in filenames:
|
|
||||||
if not p.check():
|
|
||||||
log("path %s not found, ignoring" % p)
|
|
||||||
continue
|
|
||||||
def fil(p):
|
|
||||||
return p.check(fnmatch='*.txt', versioned=True)
|
|
||||||
def rec(p):
|
|
||||||
return p.check(dotfile=0)
|
|
||||||
if p.check(dir=1):
|
|
||||||
for x in p.visit(fil, rec):
|
|
||||||
rest.process(x)
|
|
||||||
elif p.check(file=1):
|
|
||||||
if p.ext == ".rst2pdfconfig":
|
|
||||||
directive.set_backend_and_register_directives("latex")
|
|
||||||
process_configfile(p, options.debug)
|
|
||||||
else:
|
|
||||||
if options.topdf:
|
|
||||||
cfg = p.new(ext=".rst2pdfconfig")
|
|
||||||
if cfg.check():
|
|
||||||
print "using config file %s" % (cfg, )
|
|
||||||
process_configfile(cfg, options.debug)
|
|
||||||
else:
|
|
||||||
process_rest_file(p.localpath,
|
|
||||||
options.stylesheet,
|
|
||||||
options.debug)
|
|
||||||
else:
|
|
||||||
rest.process(p)
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
from _findpy import py
|
||||||
from _findpy import py
|
py.cmdline.pytest()
|
||||||
py.test.cmdline.main()
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
@echo off
|
||||||
|
python "%~dp0\..\py.cleanup" %*
|
|
@ -0,0 +1,2 @@
|
||||||
|
@echo off
|
||||||
|
python "%~dp0\..\py.countloc" %*
|
|
@ -0,0 +1,2 @@
|
||||||
|
@echo off
|
||||||
|
python "%~dp0\..\py.lookup" %*
|
|
@ -0,0 +1,2 @@
|
||||||
|
@echo off
|
||||||
|
python "%~dp0\..\py.rest" %*
|
|
@ -0,0 +1,2 @@
|
||||||
|
@echo off
|
||||||
|
python "%~dp0\..\py.test" %*
|
|
@ -0,0 +1 @@
|
||||||
|
#
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""\
|
||||||
|
py.cleanup [PATH]
|
||||||
|
|
||||||
|
Delete pyc file recursively, starting from PATH (which defaults to the current
|
||||||
|
working directory). Don't follow links and don't recurse into directories with
|
||||||
|
a ".".
|
||||||
|
"""
|
||||||
|
import py
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = py.compat.optparse.OptionParser(usage=__doc__)
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
if not args:
|
||||||
|
args = ["."]
|
||||||
|
for arg in args:
|
||||||
|
path = py.path.local(arg)
|
||||||
|
print "cleaning path", path
|
||||||
|
for x in path.visit('*.pyc', lambda x: x.check(dotfile=0, link=0)):
|
||||||
|
x.remove()
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# hands on script to compute the non-empty Lines of Code
|
||||||
|
# for tests and non-test code
|
||||||
|
|
||||||
|
"""\
|
||||||
|
py.countloc [PATHS]
|
||||||
|
|
||||||
|
Count (non-empty) lines of python code and number of python files recursively
|
||||||
|
starting from a list of paths given on the command line (starting from the
|
||||||
|
current working directory). Distinguish between test files and normal ones and
|
||||||
|
report them separately.
|
||||||
|
"""
|
||||||
|
from _findpy import py
|
||||||
|
import py
|
||||||
|
from py.compat import optparse
|
||||||
|
from py.__.misc.cmdline.countloc import countloc
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = optparse.OptionParser(usage=__doc__)
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
countloc(args)
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""\
|
||||||
|
py.lookup SEARCH_STRING [options]
|
||||||
|
|
||||||
|
Looks recursively at Python files for a SEARCH_STRING, starting from the
|
||||||
|
present working directory. Prints the line, with the filename and line-number
|
||||||
|
prepended."""
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
import py
|
||||||
|
from py.__.misc.terminal_helper import ansi_print, terminal_width
|
||||||
|
import re
|
||||||
|
|
||||||
|
curdir = py.path.local()
|
||||||
|
def rec(p):
|
||||||
|
return p.check(dotfile=0)
|
||||||
|
|
||||||
|
optparse = py.compat.optparse
|
||||||
|
|
||||||
|
parser = optparse.OptionParser(usage=__doc__)
|
||||||
|
parser.add_option("-i", "--ignore-case", action="store_true", dest="ignorecase",
|
||||||
|
help="ignore case distinctions")
|
||||||
|
parser.add_option("-C", "--context", action="store", type="int", dest="context",
|
||||||
|
default=0, help="How many lines of output to show")
|
||||||
|
|
||||||
|
def find_indexes(search_line, string):
|
||||||
|
indexes = []
|
||||||
|
before = 0
|
||||||
|
while 1:
|
||||||
|
i = search_line.find(string, before)
|
||||||
|
if i == -1:
|
||||||
|
break
|
||||||
|
indexes.append(i)
|
||||||
|
before = i + len(string)
|
||||||
|
return indexes
|
||||||
|
|
||||||
|
def main():
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
string = args[0]
|
||||||
|
if options.ignorecase:
|
||||||
|
string = string.lower()
|
||||||
|
for x in curdir.visit('*.py', rec):
|
||||||
|
try:
|
||||||
|
s = x.read()
|
||||||
|
except py.error.ENOENT:
|
||||||
|
pass # whatever, probably broken link (ie emacs lock)
|
||||||
|
searchs = s
|
||||||
|
if options.ignorecase:
|
||||||
|
searchs = s.lower()
|
||||||
|
if s.find(string) != -1:
|
||||||
|
lines = s.splitlines()
|
||||||
|
if options.ignorecase:
|
||||||
|
searchlines = s.lower().splitlines()
|
||||||
|
else:
|
||||||
|
searchlines = lines
|
||||||
|
for i, (line, searchline) in enumerate(zip(lines, searchlines)):
|
||||||
|
indexes = find_indexes(searchline, string)
|
||||||
|
if not indexes:
|
||||||
|
continue
|
||||||
|
if not options.context:
|
||||||
|
sys.stdout.write("%s:%d: " %(x.relto(curdir), i+1))
|
||||||
|
last_index = 0
|
||||||
|
for index in indexes:
|
||||||
|
sys.stdout.write(line[last_index: index])
|
||||||
|
ansi_print(line[index: index+len(string)],
|
||||||
|
file=sys.stdout, esc=31, newline=False)
|
||||||
|
last_index = index + len(string)
|
||||||
|
sys.stdout.write(line[last_index:] + "\n")
|
||||||
|
else:
|
||||||
|
context = (options.context)/2
|
||||||
|
for count in range(max(0, i-context), min(len(lines) - 1, i+context+1)):
|
||||||
|
print "%s:%d: %s" %(x.relto(curdir), count+1, lines[count].rstrip())
|
||||||
|
print "-" * terminal_width
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
invoke
|
||||||
|
|
||||||
|
py.rest filename1.txt directory
|
||||||
|
|
||||||
|
to generate html files from ReST.
|
||||||
|
|
||||||
|
It is also possible to generate pdf files using the --topdf option.
|
||||||
|
|
||||||
|
http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
import py
|
||||||
|
|
||||||
|
if hasattr(sys.stdout, 'fileno') and os.isatty(sys.stdout.fileno()):
|
||||||
|
def log(msg):
|
||||||
|
print msg
|
||||||
|
else:
|
||||||
|
def log(msg):
|
||||||
|
pass
|
||||||
|
|
||||||
|
optparse = py.compat.optparse
|
||||||
|
|
||||||
|
parser = optparse.OptionParser(usage=__doc__)
|
||||||
|
parser.add_option("--topdf", action="store_true", dest="topdf", default=False,
|
||||||
|
help="generate pdf files")
|
||||||
|
parser.add_option("--stylesheet", dest="stylesheet", default=None,
|
||||||
|
help="use specified latex style sheet")
|
||||||
|
parser.add_option("--debug", action="store_true", dest="debug",
|
||||||
|
default=False,
|
||||||
|
help="print debug output and don't delete files")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
from py.__.misc import rest
|
||||||
|
from py.__.rest import directive
|
||||||
|
from py.__.rest.latex import process_rest_file, process_configfile
|
||||||
|
except ImportError, e:
|
||||||
|
print str(e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
filenames = [py.path.svnwc()]
|
||||||
|
else:
|
||||||
|
filenames = [py.path.svnwc(x) for x in args]
|
||||||
|
|
||||||
|
if options.topdf:
|
||||||
|
directive.set_backend_and_register_directives("latex")
|
||||||
|
|
||||||
|
for p in filenames:
|
||||||
|
if not p.check():
|
||||||
|
log("path %s not found, ignoring" % p)
|
||||||
|
continue
|
||||||
|
def fil(p):
|
||||||
|
return p.check(fnmatch='*.txt', versioned=True)
|
||||||
|
def rec(p):
|
||||||
|
return p.check(dotfile=0)
|
||||||
|
if p.check(dir=1):
|
||||||
|
for x in p.visit(fil, rec):
|
||||||
|
rest.process(x)
|
||||||
|
elif p.check(file=1):
|
||||||
|
if p.ext == ".rst2pdfconfig":
|
||||||
|
directive.set_backend_and_register_directives("latex")
|
||||||
|
process_configfile(p, options.debug)
|
||||||
|
else:
|
||||||
|
if options.topdf:
|
||||||
|
cfg = p.new(ext=".rst2pdfconfig")
|
||||||
|
if cfg.check():
|
||||||
|
print "using config file %s" % (cfg, )
|
||||||
|
process_configfile(cfg, options.debug)
|
||||||
|
else:
|
||||||
|
process_rest_file(p.localpath,
|
||||||
|
options.stylesheet,
|
||||||
|
options.debug)
|
||||||
|
else:
|
||||||
|
rest.process(p)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import py
|
||||||
|
|
||||||
|
def main():
|
||||||
|
py.test.cmdline.main()
|
|
@ -0,0 +1 @@
|
||||||
|
#
|
|
@ -0,0 +1,55 @@
|
||||||
|
import py
|
||||||
|
import sys
|
||||||
|
|
||||||
|
binpath = py.path.local(py.__file__).dirpath("bin")
|
||||||
|
binwinpath = binpath.join("win32")
|
||||||
|
|
||||||
|
def setup_module(mod):
|
||||||
|
mod.tmpdir = py.test.ensuretemp(__name__)
|
||||||
|
mod.iswin32 = sys.platform == "win32"
|
||||||
|
|
||||||
|
def checkmain(name):
|
||||||
|
main = getattr(py.cmdline, name)
|
||||||
|
assert callable(main)
|
||||||
|
assert name[:2] == "py"
|
||||||
|
scriptname = "py." + name[2:]
|
||||||
|
assert binpath.join(scriptname).check()
|
||||||
|
assert binwinpath.join(scriptname + ".cmd").check()
|
||||||
|
|
||||||
|
def checkprocess(script):
|
||||||
|
assert script.check()
|
||||||
|
old = tmpdir.ensure(script.basename, dir=1).chdir()
|
||||||
|
try:
|
||||||
|
if iswin32:
|
||||||
|
cmd = script.basename
|
||||||
|
else:
|
||||||
|
cmd = "%s" %(script, )
|
||||||
|
|
||||||
|
if script.basename.startswith("py.lookup"):
|
||||||
|
cmd += " hello"
|
||||||
|
print "executing", script
|
||||||
|
try:
|
||||||
|
py.process.cmdexec(cmd)
|
||||||
|
except py.process.cmdexec.Error, e:
|
||||||
|
if cmd.find("py.rest") != -1 and \
|
||||||
|
e.out.find("module named") != -1:
|
||||||
|
return
|
||||||
|
raise
|
||||||
|
|
||||||
|
finally:
|
||||||
|
old.chdir()
|
||||||
|
|
||||||
|
def test_cmdline_namespace():
|
||||||
|
for name in dir(py.cmdline):
|
||||||
|
if name[0] != "_":
|
||||||
|
yield checkmain, name
|
||||||
|
|
||||||
|
def test_script_invocation():
|
||||||
|
if iswin32:
|
||||||
|
for script in binwinpath.listdir("py.*"):
|
||||||
|
assert script.ext == ".cmd"
|
||||||
|
yield checkprocess, script
|
||||||
|
else:
|
||||||
|
for script in binpath.listdir("py.*"):
|
||||||
|
yield checkprocess, script
|
||||||
|
|
|
@ -1,104 +1,71 @@
|
||||||
Download and Installation of the py lib
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
.. contents::
|
|
||||||
.. sectnum::
|
|
||||||
|
|
||||||
Downloading a tar/zip file and installing it
|
"easy_install py"
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
The latest public release:
|
With a working `setuptools installation`_ you can install from the command line::
|
||||||
|
|
||||||
`download py-0.9.0.tar.gz`_
|
easy_install py
|
||||||
`download py-0.9.0.zip`_
|
|
||||||
|
|
||||||
.. _`download py-0.9.0.tar.gz`: http://codespeak.net/download/py/py-0.9.0.tar.gz
|
to get the latest release of the py lib. On non-Windows systems you will
|
||||||
.. _`download py-0.9.0.zip`: http://codespeak.net/download/py/py-0.9.0.zip
|
need a working C-compiler in order to successfully complete this step.
|
||||||
|
The py lib and its tools are expected to work well on Linux, Windows
|
||||||
|
and OSX, Python versions 2.3, 2.4, 2.5 and 2.6.
|
||||||
|
|
||||||
The py lib can be `globally installed via setup.py`_
|
**IMPORTANT NOTE**: if you are using Windows and have previous
|
||||||
or `used locally`_.
|
installations of the py lib on your system, please download
|
||||||
|
and execute http://codespeak.net/svn/py/build/winpathclean.py
|
||||||
|
This will check that no previous files are getting in the way.
|
||||||
|
(Unfortunately we don't know about a way to execute this
|
||||||
|
code automatically during the above install).
|
||||||
|
|
||||||
WARNING: win32 there is no pre-packaged c-extension
|
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools
|
||||||
module (greenlet) yet and thus greenlets will not work
|
|
||||||
out of the box.
|
|
||||||
|
|
||||||
Getting (and updating) via subversion
|
Downloading a tar/zip archive and installing that
|
||||||
--------------------------------------------
|
===================================================
|
||||||
|
|
||||||
Use Subversion to checkout the latest 0.9.x stable release:
|
Go to the project pages and download a tar or zip file:
|
||||||
|
|
||||||
svn co http://codespeak.net/svn/py/release/0.9.x py-0.9.x
|
http://pypi.python.org/pypi/py/
|
||||||
|
|
||||||
to obtain the complete code and documentation source.
|
and unpack it to a directory, where you then type::
|
||||||
|
|
||||||
If you experience problems with the subversion checkout e.g.
|
|
||||||
because you have a http-proxy in between that doesn't proxy
|
|
||||||
DAV requests you can try to use "codespeak.net:8080" instead
|
|
||||||
of just "codespeak.net". Alternatively, you may tweak
|
|
||||||
your local subversion installation.
|
|
||||||
|
|
||||||
If you want to follow stable snapshots
|
|
||||||
then you may use the equivalent of this invocation:
|
|
||||||
|
|
||||||
svn co http://codespeak.net/svn/py/dist py-dist
|
|
||||||
|
|
||||||
|
|
||||||
.. _`globally installed via setup.py`:
|
|
||||||
|
|
||||||
Installation via setup.py
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
Go to your unpacked/checked out directory
|
|
||||||
and issue:
|
|
||||||
|
|
||||||
python setup.py install
|
python setup.py install
|
||||||
|
|
||||||
|
If you don't have a working C-compiler you can do::
|
||||||
|
|
||||||
.. _`used locally`:
|
python setup.py install_lib
|
||||||
|
|
||||||
Local Installation/Usage
|
You will then not be able to use greenlets but otherwise
|
||||||
------------------------------
|
should be fine.
|
||||||
|
|
||||||
You need to put the checkout-directory into your ``PYTHONPATH``
|
Installing from subversion / develop mode
|
||||||
and you want to have the ``py-dist/py/bin/py.test`` script in
|
============================================
|
||||||
your (unixish) system path, which lets you execute test files
|
|
||||||
and directories.
|
|
||||||
|
|
||||||
There is a convenient way for Bash/Shell based systems
|
To follow development or help with fixing things
|
||||||
to setup the ``PYTHONPATH`` as well as the shell ``PATH``, insert::
|
for the next release, checkout the complete code
|
||||||
|
and documentation source::
|
||||||
|
|
||||||
eval `python ~/path/to/py-dist/py/env.py`
|
svn co http://codespeak.net/svn/py/release/0.9.x py-0.9.x
|
||||||
|
|
||||||
into your ``.bash_profile``. Of course, you need to
|
You should then be able to issue::
|
||||||
specify your own checkout-directory.
|
|
||||||
|
|
||||||
|
python setup.py develop
|
||||||
|
|
||||||
.. _`svn-external scenario`:
|
and work with the local version.
|
||||||
|
|
||||||
The py lib as an svn external
|
If this doesn't work for you then you can also
|
||||||
-------------------------------------------------------
|
source (linux) or execute (windows) some scripts
|
||||||
|
that set environment variables for using your checkout.
|
||||||
|
You can execute:
|
||||||
|
|
||||||
Add the py lib as an external to your project `DIRECTORY`
|
python ~/path/to/checkout/py/env.py
|
||||||
which contains your svn-controlled root package::
|
|
||||||
|
|
||||||
svn propedit 'svn:externals' DIRECTORY
|
or on windows:
|
||||||
|
|
||||||
which will open an editor where you can add
|
\\path\\to\\checkout\\py\\env.cmd
|
||||||
the following line:
|
|
||||||
|
|
||||||
py http://codespeak.net/svn/py/dist
|
to get settings for PYTHONPATH and PATH.
|
||||||
|
|
||||||
This will make your projcet automatically use the
|
|
||||||
most recent stable snapshot of the py lib.
|
|
||||||
|
|
||||||
Alternatively you may use this url for
|
|
||||||
integrating the development version:
|
|
||||||
|
|
||||||
http://codespeak.net/svn/py/trunk
|
|
||||||
|
|
||||||
or the next one for following the e.g. the 0.9 release branch
|
|
||||||
|
|
||||||
http://codespeak.net/svn/py/release/0.9.x
|
|
||||||
|
|
||||||
|
|
||||||
py subversion directory structure
|
py subversion directory structure
|
||||||
|
|
|
@ -5,8 +5,6 @@ Implementation and Customization of ``py.test``
|
||||||
.. contents::
|
.. contents::
|
||||||
.. sectnum::
|
.. sectnum::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _`basicpicture`:
|
.. _`basicpicture`:
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,6 +69,12 @@ By default all directories not starting with a dot are traversed,
|
||||||
looking for ``test_*.py`` and ``*_test.py`` files. Those files
|
looking for ``test_*.py`` and ``*_test.py`` files. Those files
|
||||||
are imported under their `package name`_.
|
are imported under their `package name`_.
|
||||||
|
|
||||||
|
The Module collector looks for test functions
|
||||||
|
and test classes and methods. Test functions and methods
|
||||||
|
are prefixed ``test`` by default. Test classes must
|
||||||
|
start with a capitalized ``Test`` prefix.
|
||||||
|
|
||||||
|
|
||||||
.. _`collector API`:
|
.. _`collector API`:
|
||||||
|
|
||||||
test items are collectors as well
|
test items are collectors as well
|
||||||
|
@ -84,48 +88,28 @@ it, otherwise we consider the "test" as passed.
|
||||||
|
|
||||||
.. _`package name`:
|
.. _`package name`:
|
||||||
|
|
||||||
constructing the package name for modules
|
constructing the package name for test modules
|
||||||
-----------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
Test modules are imported under their fully qualified
|
Test modules are imported under their fully qualified
|
||||||
name. Given a module ``path`` the fully qualified package
|
name. Given a filesystem ``fspath`` it is constructed as follows:
|
||||||
name is constructed as follows:
|
|
||||||
|
|
||||||
* determine the last "upward" directory from ``path`` that
|
* walk the directories up to the last one that contains
|
||||||
contains an ``__init__.py`` file. Going upwards
|
an ``__init__.py`` file.
|
||||||
means repeatedly calling the ``dirpath()`` method
|
|
||||||
on a path object (which returns the parent directory
|
|
||||||
as a path object).
|
|
||||||
|
|
||||||
* insert this base directory into the sys.path list
|
* perform ``sys.path.insert(0, basedir)``.
|
||||||
as its first element
|
|
||||||
|
|
||||||
* import the root package
|
* import the root package as ``root``
|
||||||
|
|
||||||
* determine the fully qualified name for the module located
|
* determine the fully qualified name for ``fspath`` by either:
|
||||||
at ``path`` ...
|
|
||||||
|
|
||||||
* if the imported root package has a __package__ object
|
* calling ``root.__pkg__.getimportname(fspath)`` if the
|
||||||
then call ``__package__.getimportname(path)``
|
``__pkg__`` exists.` or
|
||||||
|
|
||||||
* otherwise use the relative path of the module path to
|
* otherwise use the relative path of the module path to
|
||||||
the base dir and turn slashes into dots and strike
|
the base dir and turn slashes into dots and strike
|
||||||
the trailing ``.py``.
|
the trailing ``.py``.
|
||||||
|
|
||||||
The Module collector will eventually trigger
|
|
||||||
``__import__(mod_fqdnname, ...)`` to finally get to
|
|
||||||
the live module object.
|
|
||||||
|
|
||||||
Side note: this whole logic is performed by local path
|
|
||||||
object's ``pyimport()`` method.
|
|
||||||
|
|
||||||
Module Collector
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The default Module collector looks for test functions
|
|
||||||
and test classes and methods. Test functions and methods
|
|
||||||
are prefixed ``test`` by default. Test classes must
|
|
||||||
start with a capitalized ``Test`` prefix.
|
|
||||||
|
|
||||||
|
|
||||||
Customizing the testing process
|
Customizing the testing process
|
||||||
|
@ -256,32 +240,27 @@ Customizing the collection process in a module
|
||||||
If you have a module where you want to take responsibility for
|
If you have a module where you want to take responsibility for
|
||||||
collecting your own test Items and possibly even for executing
|
collecting your own test Items and possibly even for executing
|
||||||
a test then you can provide `generative tests`_ that yield
|
a test then you can provide `generative tests`_ that yield
|
||||||
callables and possibly arguments as a tuple. This should
|
callables and possibly arguments as a tuple. This is especially
|
||||||
serve some immediate purposes like paramtrized tests.
|
useful for calling application test machinery with different
|
||||||
|
parameter sets but counting each of the calls as a separate
|
||||||
|
tests.
|
||||||
|
|
||||||
.. _`generative tests`: test.html#generative-tests
|
.. _`generative tests`: test.html#generative-tests
|
||||||
|
|
||||||
The other extension possibility goes deeper into the machinery
|
The other extension possibility is about
|
||||||
and allows you to specify a custom test ``Item`` class which
|
specifying a custom test ``Item`` class which
|
||||||
is responsible for setting up and executing an underlying
|
is responsible for setting up and executing an underlying
|
||||||
test. [XXX not working: You can integrate your custom ``py.test.collect.Item`` subclass
|
test. Or you can extend the collection process for a whole
|
||||||
by binding an ``Item`` name to a test class.] Or you can
|
directory tree by putting Items in a ``conftest.py`` configuration file.
|
||||||
extend the collection process for a whole directory tree
|
The collection process dynamically consults the *chain of conftest.py*
|
||||||
by putting Items in a ``conftest.py`` configuration file.
|
modules to determine collectors and items at ``Directory``, ``Module``,
|
||||||
The collection process constantly looks at according names
|
``Class``, ``Function`` or ``Generator`` level respectively.
|
||||||
in the *chain of conftest.py* modules to determine collectors
|
|
||||||
and items at ``Directory``, ``Module``, ``Class``, ``Function``
|
|
||||||
or ``Generator`` level. Note that, right now, except for ``Function``
|
|
||||||
items all classes are pure collectors, i.e. will return a list
|
|
||||||
of names (possibly empty).
|
|
||||||
|
|
||||||
XXX implement doctests as alternatives to ``Function`` items.
|
|
||||||
|
|
||||||
Customizing execution of Functions
|
Customizing execution of Functions
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
- Function test items allow total control of executing their
|
- ``py.test.collect.Function`` test items control execution
|
||||||
contained test method. ``function.run()`` will get called by the
|
of a test function. ``function.run()`` will get called by the
|
||||||
session in order to actually run a test. The method is responsible
|
session in order to actually run a test. The method is responsible
|
||||||
for performing proper setup/teardown ("Test Fixtures") for a
|
for performing proper setup/teardown ("Test Fixtures") for a
|
||||||
Function test.
|
Function test.
|
||||||
|
@ -290,5 +269,4 @@ Customizing execution of Functions
|
||||||
the default ``Function.run()`` to actually execute a python
|
the default ``Function.run()`` to actually execute a python
|
||||||
function with the given (usually empty set of) arguments.
|
function with the given (usually empty set of) arguments.
|
||||||
|
|
||||||
|
|
||||||
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev
|
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
py lib documentation
|
py lib documentation
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
The py lib aims at supporting a decent development process
|
The py lib is a development support library featuring
|
||||||
addressing deployment, versioning, testing and documentation
|
py.test, ad-hoc distributed execution, micro-threads
|
||||||
perspectives.
|
(greenlets) and uniform local path and svn abstractions.
|
||||||
|
Works on Linux, Windows and OSX, Python versions
|
||||||
|
2.3, 2.4, 2.5 and 2.6.
|
||||||
|
|
||||||
`Download and Installation`_
|
`Download and Installation`_
|
||||||
|
|
||||||
`0.9.0 release announcement`_
|
`0.9.2 release announcement`_
|
||||||
|
|
||||||
Main tools and API
|
Main tools and API
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -20,6 +22,8 @@ Main tools and API
|
||||||
|
|
||||||
`py.path`_: local and subversion Path and Filesystem access
|
`py.path`_: local and subversion Path and Filesystem access
|
||||||
|
|
||||||
|
`py.code`_: High-level access/manipulation of Python code and traceback objects.
|
||||||
|
|
||||||
`py lib scripts`_ describe the scripts contained in the ``py/bin`` directory.
|
`py lib scripts`_ describe the scripts contained in the ``py/bin`` directory.
|
||||||
|
|
||||||
`apigen`_: a new way to generate rich Python API documentation
|
`apigen`_: a new way to generate rich Python API documentation
|
||||||
|
@ -27,8 +31,6 @@ Main tools and API
|
||||||
support functionality
|
support functionality
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
`py.code`_: High-level access/manipulation of Python code and traceback objects.
|
|
||||||
|
|
||||||
`py.xml`_ for generating in-memory xml/html object trees
|
`py.xml`_ for generating in-memory xml/html object trees
|
||||||
|
|
||||||
`py.io`_: Helper Classes for Capturing of Input/Output
|
`py.io`_: Helper Classes for Capturing of Input/Output
|
||||||
|
@ -59,4 +61,4 @@ Background and Motivation information
|
||||||
.. _`Why What how py?`: why_py.html
|
.. _`Why What how py?`: why_py.html
|
||||||
.. _`future`: future.html
|
.. _`future`: future.html
|
||||||
.. _`miscellaneous features`: misc.html
|
.. _`miscellaneous features`: misc.html
|
||||||
.. _`0.9.0 release announcement`: release-0.9.0.html
|
.. _`0.9.2 release announcement`: release-0.9.2.html
|
||||||
|
|
|
@ -5,7 +5,7 @@ Welcome to the 0.9.2 py lib and py.test release -
|
||||||
mainly fixing Windows issues, providing better
|
mainly fixing Windows issues, providing better
|
||||||
packaging and integration with setuptools.
|
packaging and integration with setuptools.
|
||||||
|
|
||||||
Summary of main feature of the py lib:
|
Here is a quick summary of what it provides:
|
||||||
|
|
||||||
* py.test: cross-project testing tool with many advanced features
|
* py.test: cross-project testing tool with many advanced features
|
||||||
* py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes
|
* py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes
|
||||||
|
@ -17,6 +17,7 @@ Summary of main feature of the py lib:
|
||||||
See here for more information:
|
See here for more information:
|
||||||
|
|
||||||
Download/Install: http://codespeak.net/py/0.9.2/download.html
|
Download/Install: http://codespeak.net/py/0.9.2/download.html
|
||||||
|
|
||||||
Documentation/API: http://codespeak.net/py/0.9.2/index.html
|
Documentation/API: http://codespeak.net/py/0.9.2/index.html
|
||||||
|
|
||||||
best and have fun,
|
best and have fun,
|
||||||
|
|
|
@ -59,10 +59,6 @@ import sys
|
||||||
class Popen2IO:
|
class Popen2IO:
|
||||||
server_stmt = """
|
server_stmt = """
|
||||||
import os, sys, StringIO
|
import os, sys, StringIO
|
||||||
if sys.platform == "win32":
|
|
||||||
import msvcrt
|
|
||||||
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
|
|
||||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
|
||||||
io = Popen2IO(sys.stdout, sys.stdin)
|
io = Popen2IO(sys.stdout, sys.stdin)
|
||||||
sys.stdout = sys.stderr = StringIO.StringIO()
|
sys.stdout = sys.stderr = StringIO.StringIO()
|
||||||
#try:
|
#try:
|
||||||
|
@ -75,6 +71,11 @@ sys.stdout = sys.stderr = StringIO.StringIO()
|
||||||
|
|
||||||
def __init__(self, infile, outfile):
|
def __init__(self, infile, outfile):
|
||||||
self.outfile, self.infile = infile, outfile
|
self.outfile, self.infile = infile, outfile
|
||||||
|
if sys.platform == "win32":
|
||||||
|
import msvcrt
|
||||||
|
msvcrt.setmode(infile.fileno(), os.O_BINARY)
|
||||||
|
msvcrt.setmode(outfile.fileno(), os.O_BINARY)
|
||||||
|
|
||||||
self.readable = self.writeable = True
|
self.readable = self.writeable = True
|
||||||
self.lock = thread.allocate_lock()
|
self.lock = thread.allocate_lock()
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
import os, inspect, socket
|
import os, inspect, socket
|
||||||
import sys
|
import sys
|
||||||
from py.magic import autopath ; mypath = autopath()
|
from py.magic import autopath ; mypath = autopath()
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
if sys.platform == "win32":
|
||||||
|
win32 = True
|
||||||
|
import msvcrt
|
||||||
|
else:
|
||||||
|
win32 = False
|
||||||
|
|
||||||
# the list of modules that must be send to the other side
|
# the list of modules that must be send to the other side
|
||||||
# for bootstrapping gateways
|
# for bootstrapping gateways
|
||||||
|
@ -51,13 +55,10 @@ class InstallableGateway(gateway.Gateway):
|
||||||
class PopenCmdGateway(InstallableGateway):
|
class PopenCmdGateway(InstallableGateway):
|
||||||
def __init__(self, cmd):
|
def __init__(self, cmd):
|
||||||
infile, outfile = os.popen2(cmd)
|
infile, outfile = os.popen2(cmd)
|
||||||
if sys.platform == 'win32':
|
|
||||||
import msvcrt
|
|
||||||
msvcrt.setmode(infile.fileno(), os.O_BINARY)
|
|
||||||
msvcrt.setmode(outfile.fileno(), os.O_BINARY)
|
|
||||||
io = inputoutput.Popen2IO(infile, outfile)
|
io = inputoutput.Popen2IO(infile, outfile)
|
||||||
super(PopenCmdGateway, self).__init__(io=io)
|
super(PopenCmdGateway, self).__init__(io=io)
|
||||||
|
|
||||||
|
|
||||||
class PopenGateway(PopenCmdGateway):
|
class PopenGateway(PopenCmdGateway):
|
||||||
""" This Gateway provides interaction with a newly started
|
""" This Gateway provides interaction with a newly started
|
||||||
python subprocess.
|
python subprocess.
|
||||||
|
|
|
@ -3,6 +3,9 @@ A utility to build a Python extension module from C, wrapping distutils.
|
||||||
"""
|
"""
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
# set to true for automatic re-compilation of extensions
|
||||||
|
AUTOREGEN = True
|
||||||
|
|
||||||
# XXX we should distutils in a subprocess, because it messes up the
|
# XXX we should distutils in a subprocess, because it messes up the
|
||||||
# environment and who knows what else. Currently we just save
|
# environment and who knows what else. Currently we just save
|
||||||
# and restore os.environ.
|
# and restore os.environ.
|
||||||
|
@ -32,7 +35,7 @@ def make_module_from_c(cfile):
|
||||||
lib = dirpath.join(modname+ext)
|
lib = dirpath.join(modname+ext)
|
||||||
|
|
||||||
# XXX argl! we need better "build"-locations alltogether!
|
# XXX argl! we need better "build"-locations alltogether!
|
||||||
if lib.check() and lib.stat().mtime < cfile.stat().mtime:
|
if lib.check() and AUTOREGEN and lib.stat().mtime < cfile.stat().mtime:
|
||||||
try:
|
try:
|
||||||
lib.remove()
|
lib.remove()
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
|
|
|
@ -8,6 +8,10 @@ def test_win_killsubprocess():
|
||||||
py.test.skip("you\'re using an older version of windows, which "
|
py.test.skip("you\'re using an older version of windows, which "
|
||||||
"doesn\'t support 'taskkill' - py.misc.killproc is not "
|
"doesn\'t support 'taskkill' - py.misc.killproc is not "
|
||||||
"available")
|
"available")
|
||||||
|
try:
|
||||||
|
import subprocess
|
||||||
|
except ImportError:
|
||||||
|
py.test.skip("no subprocess module")
|
||||||
tmp = py.test.ensuretemp("test_win_killsubprocess")
|
tmp = py.test.ensuretemp("test_win_killsubprocess")
|
||||||
t = tmp.join("t.py")
|
t = tmp.join("t.py")
|
||||||
t.write("import time ; time.sleep(100)")
|
t.write("import time ; time.sleep(100)")
|
||||||
|
|
156
setup.py
156
setup.py
|
@ -1,25 +1,46 @@
|
||||||
"""
|
"""
|
||||||
setup file for 'py' package based on:
|
setup file for 'py' package based on:
|
||||||
|
|
||||||
https://codespeak.net/svn/py/trunk, revision=57462
|
https://codespeak.net/svn/py/trunk, revision=57536
|
||||||
|
|
||||||
autogenerated by gensetup.py
|
autogenerated by gensetup.py
|
||||||
"""
|
"""
|
||||||
import os, sys
|
import os, sys
|
||||||
|
|
||||||
if 1: # set to zero if you want plain distutils
|
import ez_setup
|
||||||
import ez_setup
|
ez_setup.use_setuptools()
|
||||||
ez_setup.use_setuptools()
|
from setuptools import setup, Extension
|
||||||
from setuptools import setup, Extension
|
|
||||||
else:
|
|
||||||
from distutils.core import setup, Extension
|
|
||||||
|
|
||||||
|
long_description = """
|
||||||
|
|
||||||
|
The py lib is a development support library featuring these tools and APIs:
|
||||||
|
|
||||||
|
- `py.test`_: cross-project testing tool with many advanced features
|
||||||
|
- `py.execnet`_: ad-hoc code distribution to SSH, Socket and local sub processes
|
||||||
|
- `py.magic.greenlet`_: micro-threads on standard CPython ("stackless-light") and PyPy
|
||||||
|
- `py.path`_: path abstractions over local and subversion files
|
||||||
|
- `py.code`_: dynamic code compile and traceback printing support
|
||||||
|
|
||||||
|
The py lib and its tools should work well on Linux, Win32,
|
||||||
|
OSX, Python versions 2.3-2.6. For questions please go to
|
||||||
|
http://pylib.org/contact.html
|
||||||
|
|
||||||
|
.. _`py.test`: http://pylib.org/test.html
|
||||||
|
.. _`py.execnet`: http://pylib.org/execnet.html
|
||||||
|
.. _`py.magic.greenlet`: http://pylib.org/greenlet.html
|
||||||
|
.. _`py.path`: http://pylib.org/path.html
|
||||||
|
.. _`py.code`: http://pylib.org/code.html
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
def main():
|
def main():
|
||||||
setup(cmdclass=cmdclass,
|
setup(
|
||||||
name='py',
|
name='py',
|
||||||
description='pylib and py.test: agile development and test support library',
|
description='pylib and py.test: agile development and test support library',
|
||||||
|
long_description = long_description,
|
||||||
version='1.0.0a1',
|
version='1.0.0a1',
|
||||||
url='http://pylib.org',
|
url='http://pylib.org',
|
||||||
|
download_url='http://codespeak.net/py/0.9.2/download.html',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
author='holger krekel, Guido Wesdorp, Carl Friedrich Bolz, Armin Rigo, Maciej Fijalkowski & others',
|
author='holger krekel, Guido Wesdorp, Carl Friedrich Bolz, Armin Rigo, Maciej Fijalkowski & others',
|
||||||
|
@ -27,9 +48,13 @@ def main():
|
||||||
ext_modules = [Extension("py.c-extension.greenlet.greenlet",
|
ext_modules = [Extension("py.c-extension.greenlet.greenlet",
|
||||||
["py/c-extension/greenlet/greenlet.c"]),],
|
["py/c-extension/greenlet/greenlet.c"]),],
|
||||||
|
|
||||||
py_modules=['_findpy'],
|
entry_points={'console_scripts': ['py.cleanup = py.cmdline:pycleanup',
|
||||||
long_description='the py lib is a development support library featuring py.test, ad-hoc distributed execution, micro-threads and svn abstractions.',
|
'py.countloc = py.cmdline:pycountloc',
|
||||||
classifiers=['Development Status :: 3 - Alpha',
|
'py.lookup = py.cmdline:pylookup',
|
||||||
|
'py.rest = py.cmdline:pyrest',
|
||||||
|
'py.test = py.cmdline:pytest',
|
||||||
|
'py.which = py.cmdline:pywhich']},
|
||||||
|
classifiers=['Development Status :: 4 - Beta',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Operating System :: POSIX',
|
'Operating System :: POSIX',
|
||||||
|
@ -40,12 +65,6 @@ def main():
|
||||||
'Topic :: System :: Distributed Computing',
|
'Topic :: System :: Distributed Computing',
|
||||||
'Topic :: Utilities',
|
'Topic :: Utilities',
|
||||||
'Programming Language :: Python'],
|
'Programming Language :: Python'],
|
||||||
scripts=['py/bin/py.cleanup',
|
|
||||||
'py/bin/py.countloc',
|
|
||||||
'py/bin/py.lookup',
|
|
||||||
'py/bin/py.rest',
|
|
||||||
'py/bin/py.test',
|
|
||||||
'py/bin/py.which'],
|
|
||||||
packages=['py',
|
packages=['py',
|
||||||
'py.apigen',
|
'py.apigen',
|
||||||
'py.apigen.rest',
|
'py.apigen.rest',
|
||||||
|
@ -61,6 +80,8 @@ def main():
|
||||||
'py.builtin',
|
'py.builtin',
|
||||||
'py.builtin.testing',
|
'py.builtin.testing',
|
||||||
'py.c-extension',
|
'py.c-extension',
|
||||||
|
'py.cmdline',
|
||||||
|
'py.cmdline.testing',
|
||||||
'py.code',
|
'py.code',
|
||||||
'py.code.testing',
|
'py.code.testing',
|
||||||
'py.compat',
|
'py.compat',
|
||||||
|
@ -117,13 +138,20 @@ def main():
|
||||||
'apigen/style.css',
|
'apigen/style.css',
|
||||||
'apigen/todo-apigen.txt',
|
'apigen/todo-apigen.txt',
|
||||||
'apigen/todo.txt',
|
'apigen/todo.txt',
|
||||||
|
'bin/_docgen.py',
|
||||||
'bin/_findpy.py',
|
'bin/_findpy.py',
|
||||||
|
'bin/_genscripts.py',
|
||||||
'bin/py.cleanup',
|
'bin/py.cleanup',
|
||||||
'bin/py.countloc',
|
'bin/py.countloc',
|
||||||
'bin/py.lookup',
|
'bin/py.lookup',
|
||||||
'bin/py.rest',
|
'bin/py.rest',
|
||||||
'bin/py.test',
|
'bin/py.test',
|
||||||
'bin/py.which',
|
'bin/py.which',
|
||||||
|
'bin/win32/py.cleanup.cmd',
|
||||||
|
'bin/win32/py.countloc.cmd',
|
||||||
|
'bin/win32/py.lookup.cmd',
|
||||||
|
'bin/win32/py.rest.cmd',
|
||||||
|
'bin/win32/py.test.cmd',
|
||||||
'c-extension/greenlet/README.txt',
|
'c-extension/greenlet/README.txt',
|
||||||
'c-extension/greenlet/dummy_greenlet.py',
|
'c-extension/greenlet/dummy_greenlet.py',
|
||||||
'c-extension/greenlet/greenlet.c',
|
'c-extension/greenlet/greenlet.c',
|
||||||
|
@ -201,100 +229,6 @@ def main():
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Win32PathHandling:
|
|
||||||
""" a helper to remove things added to system PATHs in previous installations. """
|
|
||||||
_winreg = None
|
|
||||||
def __init__(self):
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
try:
|
|
||||||
import _winreg
|
|
||||||
except ImportError:
|
|
||||||
print sys.stderr, "huh could not import _winreg on windows, ignoring"
|
|
||||||
else:
|
|
||||||
self._winreg = _winreg
|
|
||||||
|
|
||||||
def remove_pylib_path(self):
|
|
||||||
reg = self._winreg.ConnectRegistry(
|
|
||||||
None, self._winreg.HKEY_LOCAL_MACHINE)
|
|
||||||
key = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
|
|
||||||
path = self.get_registry_value(reg, key, "Path")
|
|
||||||
newpath = self.prunepath(path)
|
|
||||||
if newpath != path:
|
|
||||||
print "PATH contains old py/bin/win32 scripts:", path
|
|
||||||
print "pruning and setting a new PATH:", newpath
|
|
||||||
self.set_registry_value(reg, key, "Path", newpath)
|
|
||||||
# Propagate changes to current command prompt
|
|
||||||
os.system("set PATH=%s" % path)
|
|
||||||
self.try_propagate_system()
|
|
||||||
|
|
||||||
def prunepath(self, path):
|
|
||||||
basename = os.path.basename
|
|
||||||
dirname = os.path.dirname
|
|
||||||
l = []
|
|
||||||
for p in path.split(';'):
|
|
||||||
if basename(p) == "win32" and basename(dirname(p)) == "bin" \
|
|
||||||
and basename(dirname(dirname(p))) == "py":
|
|
||||||
continue # prune this path
|
|
||||||
l.append(p)
|
|
||||||
return ";".join(l)
|
|
||||||
|
|
||||||
def try_propagate_system(self):
|
|
||||||
try:
|
|
||||||
import win32gui, win32con
|
|
||||||
except ImportError:
|
|
||||||
return
|
|
||||||
# Propagate changes throughout the system
|
|
||||||
win32gui.SendMessageTimeout(win32con.HWND_BROADCAST,
|
|
||||||
win32con.WM_SETTINGCHANGE, 0, "Environment",
|
|
||||||
win32con.SMTO_ABORTIFHUNG, 5000)
|
|
||||||
|
|
||||||
def get_registry_value(self, reg, key, value_name):
|
|
||||||
k = self._winreg.OpenKey(reg, key)
|
|
||||||
value = self._winreg.QueryValueEx(k, value_name)[0]
|
|
||||||
self._winreg.CloseKey(k)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def set_registry_value(self, reg, key, value_name, value):
|
|
||||||
k = self._winreg.OpenKey(reg, key, 0, self._winreg.KEY_WRITE)
|
|
||||||
value_type = self._winreg.REG_SZ
|
|
||||||
# if we handle the Path value, then set its type to REG_EXPAND_SZ
|
|
||||||
# so that things like %SystemRoot% get automatically expanded by the
|
|
||||||
# command prompt
|
|
||||||
if value_name == "Path":
|
|
||||||
value_type = self._winreg.REG_EXPAND_SZ
|
|
||||||
self._winreg.SetValueEx(k, value_name, 0, value_type, value)
|
|
||||||
self._winreg.CloseKey(k)
|
|
||||||
|
|
||||||
# on windows we need to hack up the to-be-installed scripts
|
|
||||||
from distutils.command.install_scripts import install_scripts
|
|
||||||
class my_install_scripts(install_scripts):
|
|
||||||
def run(self):
|
|
||||||
install_scripts.run(self)
|
|
||||||
#print self.outfiles
|
|
||||||
for fn in self.outfiles:
|
|
||||||
basename = os.path.basename(fn)
|
|
||||||
if "." in basename:
|
|
||||||
#print "tackling", fn
|
|
||||||
newbasename = basename.replace(".", "_")
|
|
||||||
newfn = os.path.join(os.path.dirname(fn), newbasename)
|
|
||||||
if os.path.exists(newfn):
|
|
||||||
os.remove(newfn)
|
|
||||||
os.rename(fn, newfn)
|
|
||||||
newname = fn + ".cmd"
|
|
||||||
if os.path.exists(newname):
|
|
||||||
os.remove(newname)
|
|
||||||
f = open(newname, 'w')
|
|
||||||
f.write("@echo off\n")
|
|
||||||
f.write('python "%%~dp0\py_command_trampolin" %s %%*\n' % basename)
|
|
||||||
f.close()
|
|
||||||
w32path = Win32PathHandling()
|
|
||||||
w32path.remove_pylib_path()
|
|
||||||
|
|
||||||
if sys.platform == "win32":
|
|
||||||
cmdclass = {'install_scripts': my_install_scripts}
|
|
||||||
else:
|
|
||||||
cmdclass = {}
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue