parent
04c41cb672
commit
22282eedb9
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
py.test --dist=each $* \
|
|
||||||
--tx 'socket=192.168.1.106:8888'
|
|
||||||
#--tx 'popen//python=python2.6' \
|
|
||||||
#--tx 'ssh=noco//python=/usr/local/bin/python2.4//chdir=/tmp/pytest-python2.4' \
|
|
|
@ -1,76 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import py
|
|
||||||
import inspect
|
|
||||||
import types
|
|
||||||
|
|
||||||
def report_strange_docstring(name, obj):
|
|
||||||
if obj.__doc__ is None:
|
|
||||||
print "%s misses a docstring" % (name, )
|
|
||||||
elif obj.__doc__ == "":
|
|
||||||
print "%s has an empty" % (name, )
|
|
||||||
elif "XXX" in obj.__doc__:
|
|
||||||
print "%s has an 'XXX' in its docstring" % (name, )
|
|
||||||
|
|
||||||
def find_code(method):
|
|
||||||
return getattr(getattr(method, "im_func", None), "func_code", None)
|
|
||||||
|
|
||||||
def report_different_parameter_names(name, cls):
|
|
||||||
bases = cls.__mro__
|
|
||||||
for base in bases:
|
|
||||||
for attr in dir(base):
|
|
||||||
meth1 = getattr(base, attr)
|
|
||||||
code1 = find_code(meth1)
|
|
||||||
if code1 is None:
|
|
||||||
continue
|
|
||||||
if not callable(meth1):
|
|
||||||
continue
|
|
||||||
if not hasattr(cls, attr):
|
|
||||||
continue
|
|
||||||
meth2 = getattr(cls, attr)
|
|
||||||
code2 = find_code(meth2)
|
|
||||||
if not callable(meth2):
|
|
||||||
continue
|
|
||||||
if code2 is None:
|
|
||||||
continue
|
|
||||||
args1 = inspect.getargs(code1)[0]
|
|
||||||
args2 = inspect.getargs(code2)[0]
|
|
||||||
for a1, a2 in zip(args1, args2):
|
|
||||||
if a1 != a2:
|
|
||||||
print "%s.%s have different argument names %s, %s than the version in %s" % (name, attr, a1, a2, base)
|
|
||||||
|
|
||||||
|
|
||||||
def find_all_exported():
|
|
||||||
stack = [(name, getattr(py, name)) for name in dir(py)[::-1]
|
|
||||||
if not name.startswith("_") and name != "compat"]
|
|
||||||
seen = {}
|
|
||||||
exported = []
|
|
||||||
while stack:
|
|
||||||
name, obj = stack.pop()
|
|
||||||
if id(obj) in seen:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
seen[id(obj)] = True
|
|
||||||
exported.append((name, obj))
|
|
||||||
if isinstance(obj, type) or isinstance(obj, type(py)):
|
|
||||||
stack.extend([("%s.%s" % (name, s), getattr(obj, s)) for s in dir(obj)
|
|
||||||
if len(s) <= 1 or not (s[0] == '_' and s[1] != '_')])
|
|
||||||
return exported
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
all_exported = find_all_exported()
|
|
||||||
print "strange docstrings"
|
|
||||||
print "=================="
|
|
||||||
print
|
|
||||||
for name, obj in all_exported:
|
|
||||||
if callable(obj):
|
|
||||||
report_strange_docstring(name, obj)
|
|
||||||
print "\n\ndifferent parameters"
|
|
||||||
print "===================="
|
|
||||||
print
|
|
||||||
for name, obj in all_exported:
|
|
||||||
if isinstance(obj, type):
|
|
||||||
report_different_parameter_names(name, obj)
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
XXX
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from _findpy import py
|
|
||||||
try:
|
|
||||||
import apigen
|
|
||||||
except ImportError:
|
|
||||||
print 'Can not find apigen - make sure PYTHONPATH is set correctly!'
|
|
||||||
py.std.sys.exit()
|
|
||||||
else:
|
|
||||||
args = list(sys.argv[1:])
|
|
||||||
args.extend(['-p', 'apigen'])
|
|
||||||
argkeys = [a.split('=')[0] for a in args]
|
|
||||||
if '--apigen' not in argkeys:
|
|
||||||
args.append('--apigen')
|
|
||||||
if '--apigenscript' not in argkeys:
|
|
||||||
fpath = os.path.join(
|
|
||||||
os.path.dirname(apigen.__file__), 'tool', 'py_build', 'build.py')
|
|
||||||
args.append('--apigenscript=%s' % (fpath,))
|
|
||||||
if '--apigenpath' not in argkeys:
|
|
||||||
args.append('--apigenpath=api')
|
|
||||||
py.test.cmdline.main(args)
|
|
|
@ -1,33 +0,0 @@
|
||||||
import py
|
|
||||||
|
|
||||||
bindir = py.path.local(__file__).dirpath().dirpath("bin")
|
|
||||||
assert bindir.check(), bindir
|
|
||||||
|
|
||||||
def getbasename(name):
|
|
||||||
assert name[:2] == "py"
|
|
||||||
return "py." + name[2:]
|
|
||||||
|
|
||||||
def genscript_unix(name):
|
|
||||||
basename = getbasename(name)
|
|
||||||
path = bindir.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 = bindir.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,315 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.insert(0, sys.argv[1])
|
|
||||||
import py
|
|
||||||
|
|
||||||
toolpath = py.path.local(__file__)
|
|
||||||
binpath = py.path.local(py.__file__).dirpath('bin')
|
|
||||||
|
|
||||||
def error(msg):
|
|
||||||
print >>sys.stderr, msg
|
|
||||||
raise SystemExit, 1
|
|
||||||
|
|
||||||
def reformat(text):
|
|
||||||
return " ".join(text.split())
|
|
||||||
|
|
||||||
class SetupWriter(object):
|
|
||||||
EXCLUDES = ("MANIFEST.in", "contrib")
|
|
||||||
|
|
||||||
def __init__(self, basedir, pkg, setuptools=False):
|
|
||||||
self.basedir = basedir
|
|
||||||
self.setuptools = setuptools
|
|
||||||
assert self.basedir.check()
|
|
||||||
self.pkg = pkg
|
|
||||||
self.meta = pkg.__pkg__
|
|
||||||
self.lines = []
|
|
||||||
self.allpaths = self.getallpath(self.basedir)
|
|
||||||
|
|
||||||
def getallpath(self, basedir):
|
|
||||||
contrib = self.basedir.join("contrib")
|
|
||||||
allpath = []
|
|
||||||
lines = py.process.cmdexec("hg st -mcan").split("\n")
|
|
||||||
for path in lines:
|
|
||||||
p = basedir.join(path)
|
|
||||||
assert p.check(), p
|
|
||||||
if not p.relto(contrib) and p != contrib and not self.isexcluded(p):
|
|
||||||
allpath.append(p)
|
|
||||||
return allpath
|
|
||||||
|
|
||||||
def append(self, string):
|
|
||||||
lines = string.split("\n")
|
|
||||||
while lines:
|
|
||||||
if not lines[0].strip():
|
|
||||||
lines.pop(0)
|
|
||||||
continue
|
|
||||||
break
|
|
||||||
if not lines:
|
|
||||||
self.lines.append("")
|
|
||||||
return
|
|
||||||
line = lines[0]
|
|
||||||
indent = len(line) - len(line.lstrip())
|
|
||||||
for line in lines:
|
|
||||||
if line.strip():
|
|
||||||
assert not line[:indent].strip(), line
|
|
||||||
line = line[indent:]
|
|
||||||
self.lines.append(line)
|
|
||||||
|
|
||||||
def write_winfuncs(self):
|
|
||||||
self.append('''
|
|
||||||
''')
|
|
||||||
|
|
||||||
def tip_info(self, indent=8):
|
|
||||||
old = self.basedir.chdir()
|
|
||||||
indent = " " * indent
|
|
||||||
try:
|
|
||||||
info = []
|
|
||||||
output = py.process.cmdexec(
|
|
||||||
"hg tip --template '" # tags: {tags}\n"
|
|
||||||
#"branch: {branches}\n"
|
|
||||||
"revision: {rev}:{node}\n'"
|
|
||||||
)
|
|
||||||
for line in output.split("\n"):
|
|
||||||
info.append("%s %s" %(indent, line.strip()))
|
|
||||||
return "\n".join(info)
|
|
||||||
finally:
|
|
||||||
old.chdir()
|
|
||||||
|
|
||||||
def setup_header(self):
|
|
||||||
#tooltime = "%s %s" %(py.std.time.asctime(), py.std.time.tzname[0])
|
|
||||||
toolname = toolpath.basename
|
|
||||||
#toolrevision = py.path.svnwc(toolpath).info().rev
|
|
||||||
|
|
||||||
pkgname = self.pkg.__name__
|
|
||||||
self.append('"""py lib / py.test setup.py file"""')
|
|
||||||
self.append('import os, sys')
|
|
||||||
self.append("from setuptools import setup")
|
|
||||||
|
|
||||||
def setup_trailer(self):
|
|
||||||
self.append('''
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
''')
|
|
||||||
|
|
||||||
def setup_function(self):
|
|
||||||
params = self.__dict__.copy()
|
|
||||||
params.update(self.meta.__dict__)
|
|
||||||
self.append('long_description = """')
|
|
||||||
for line in params['long_description'].split('\n'):
|
|
||||||
self.append(line)
|
|
||||||
self.append('"""')
|
|
||||||
trunk = None
|
|
||||||
if params['version'] == 'trunk':
|
|
||||||
trunk = 'trunk'
|
|
||||||
self.append('trunk = %r' % trunk)
|
|
||||||
self.append('''
|
|
||||||
def main():
|
|
||||||
setup(
|
|
||||||
name=%(name)r,
|
|
||||||
description=%(description)r,
|
|
||||||
long_description = long_description,
|
|
||||||
version= trunk or %(version)r,
|
|
||||||
url=%(url)r,
|
|
||||||
license=%(license)r,
|
|
||||||
platforms=%(platforms)r,
|
|
||||||
author=%(author)r,
|
|
||||||
author_email=%(author_email)r,
|
|
||||||
''' % params)
|
|
||||||
indent = " " * 8
|
|
||||||
self.append_pprint(indent, entry_points={'console_scripts':self.getconsolescripts()})
|
|
||||||
self.append_pprint(indent, classifiers=self.meta.classifiers)
|
|
||||||
self.append_pprint(indent, packages=self.getpackages())
|
|
||||||
self.append_pprint(indent, package_data=self.getpackagedata())
|
|
||||||
self.append_pprint(indent, zip_safe=True)
|
|
||||||
self.append_pprint(indent, install_requires=['apipkg'])
|
|
||||||
self.lines.append(indent[4:] + ")\n")
|
|
||||||
|
|
||||||
def setup_scripts(self):
|
|
||||||
# XXX this was used for a different approach
|
|
||||||
not used
|
|
||||||
self.append("""
|
|
||||||
def getscripts():
|
|
||||||
if sys.platform == "win32":
|
|
||||||
base = "py/bin/win32/"
|
|
||||||
ext = ".cmd"
|
|
||||||
else:
|
|
||||||
base = "py/bin/"
|
|
||||||
ext = ""
|
|
||||||
l = []
|
|
||||||
for name in %r:
|
|
||||||
l.append(base + name + ext)
|
|
||||||
return l
|
|
||||||
""" % ([script.basename for script in binpath.listdir("py.*")]))
|
|
||||||
|
|
||||||
def append_pprint(self, indent, append=",", **kw):
|
|
||||||
for name, value in kw.items():
|
|
||||||
stringio = py.std.StringIO.StringIO()
|
|
||||||
value = py.std.pprint.pprint(value, stream=stringio)
|
|
||||||
stringio.seek(0)
|
|
||||||
lines = stringio.readlines()
|
|
||||||
line = lines.pop(0).rstrip()
|
|
||||||
self.lines.append(indent + "%s=%s" %(name, line))
|
|
||||||
indent = indent + " " * (len(name)+1)
|
|
||||||
for line in lines:
|
|
||||||
self.lines.append(indent + line.rstrip())
|
|
||||||
self.lines[-1] = self.lines[-1] + append
|
|
||||||
|
|
||||||
def getconsolescripts(self):
|
|
||||||
bindir = self.basedir.join('py', 'bin')
|
|
||||||
scripts = []
|
|
||||||
for p in self.allpaths:
|
|
||||||
if p.dirpath() == bindir:
|
|
||||||
if p.basename.startswith('py.'):
|
|
||||||
shortname = "py" + p.basename[3:]
|
|
||||||
scripts.append("%s = py.cmdline:%s" %
|
|
||||||
(p.basename, shortname))
|
|
||||||
return scripts
|
|
||||||
|
|
||||||
def getscripts(self):
|
|
||||||
bindir = self.basedir.join('py', 'bin')
|
|
||||||
scripts = []
|
|
||||||
for p in self.allpaths:
|
|
||||||
if p.dirpath() == bindir:
|
|
||||||
if p.basename.startswith('py.'):
|
|
||||||
scripts.append(p.relto(self.basedir))
|
|
||||||
return scripts
|
|
||||||
|
|
||||||
def getpackages(self):
|
|
||||||
packages = []
|
|
||||||
for p in self.allpaths: # contains no directories!
|
|
||||||
#if p.basename == "py":
|
|
||||||
# continue
|
|
||||||
if p.dirpath('__init__.py').check():
|
|
||||||
modpath = p.dirpath().relto(self.basedir).replace(p.sep, '.')
|
|
||||||
if modpath != "py" and not modpath.startswith("py."):
|
|
||||||
continue
|
|
||||||
if modpath in packages:
|
|
||||||
continue
|
|
||||||
for exclude in self.EXCLUDES:
|
|
||||||
if modpath.startswith(exclude):
|
|
||||||
print "EXCLUDING", modpath
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
packages.append(modpath)
|
|
||||||
packages.sort()
|
|
||||||
return packages
|
|
||||||
|
|
||||||
def getpackagedata(self):
|
|
||||||
datafiles = []
|
|
||||||
pkgbase = self.basedir.join(self.pkg.__name__)
|
|
||||||
for p in self.allpaths:
|
|
||||||
if p.check(file=1) and (not p.dirpath("__init__.py").check()
|
|
||||||
or p.ext != ".py"):
|
|
||||||
if p.dirpath() != self.basedir:
|
|
||||||
x = p.relto(pkgbase)
|
|
||||||
if x:
|
|
||||||
datafiles.append(p.relto(pkgbase))
|
|
||||||
return {'py': datafiles}
|
|
||||||
|
|
||||||
def getdatafiles(self):
|
|
||||||
datafiles = []
|
|
||||||
for p in self.allpaths:
|
|
||||||
if p.check(file=1) and not p.ext == ".py":
|
|
||||||
if p.dirpath() != self.basedir:
|
|
||||||
datafiles.append(p.relto(self.basedir))
|
|
||||||
return datafiles
|
|
||||||
|
|
||||||
def setup_win32(self):
|
|
||||||
import winpath
|
|
||||||
self.append(py.std.inspect.getsource(winpath))
|
|
||||||
self.append("""
|
|
||||||
from distutils.command.install import install
|
|
||||||
class my_install(install):
|
|
||||||
def finalize_other(self):
|
|
||||||
install.finalize_other(self)
|
|
||||||
on_win32_add_to_PATH()
|
|
||||||
cmdclass = {'install': my_install}
|
|
||||||
""")
|
|
||||||
|
|
||||||
def setup_win32(self):
|
|
||||||
self.append(r'''
|
|
||||||
# scripts for windows: turn "py.SCRIPT" into "py_SCRIPT" and create
|
|
||||||
# "py.SCRIPT.cmd" files invoking "py_SCRIPT"
|
|
||||||
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 basename.startswith("py.") and not basename.endswith(".cmd"):
|
|
||||||
newbasename = basename.replace(".", "_")
|
|
||||||
newfn = os.path.join(os.path.dirname(fn), newbasename)
|
|
||||||
if os.path.exists(newfn):
|
|
||||||
os.remove(newfn)
|
|
||||||
os.rename(fn, newfn)
|
|
||||||
fncmd = fn + ".cmd"
|
|
||||||
if os.path.exists(fncmd):
|
|
||||||
os.remove(fncmd)
|
|
||||||
f = open(fncmd, 'w')
|
|
||||||
f.write("@echo off\n")
|
|
||||||
f.write('python "%%~dp0\%s" %%*' %(newbasename))
|
|
||||||
f.close()
|
|
||||||
if sys.platform == "win32":
|
|
||||||
cmdclass = {'install_scripts': my_install_scripts}
|
|
||||||
else:
|
|
||||||
cmdclass = {}
|
|
||||||
''')
|
|
||||||
|
|
||||||
def write_setup(self):
|
|
||||||
self.setup_header()
|
|
||||||
self.setup_function()
|
|
||||||
#self.setup_scripts()
|
|
||||||
#self.setup_win32()
|
|
||||||
self.setup_trailer()
|
|
||||||
targetfile = self.basedir.join("setup.py")
|
|
||||||
targetfile.write("\n".join(self.lines))
|
|
||||||
print "wrote", targetfile
|
|
||||||
|
|
||||||
def isexcluded(self, wcpath):
|
|
||||||
return wcpath.basename[0] == "."
|
|
||||||
rel = wcpath.relto(self.basedir)
|
|
||||||
if rel.find("testing") != -1:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def write_manifest(self):
|
|
||||||
lines = []
|
|
||||||
for p in self.allpaths:
|
|
||||||
if p.check(dir=1):
|
|
||||||
continue
|
|
||||||
toadd = p.relto(self.basedir)
|
|
||||||
if toadd:
|
|
||||||
for exclude in self.EXCLUDES:
|
|
||||||
if toadd.startswith(exclude):
|
|
||||||
break
|
|
||||||
assert toadd.find(exclude) == -1, (toadd, exclude)
|
|
||||||
else:
|
|
||||||
lines.append("%s" %(toadd))
|
|
||||||
lines.sort()
|
|
||||||
targetfile = self.basedir.join("MANIFEST")
|
|
||||||
targetfile.write("\n".join(lines))
|
|
||||||
print "wrote", targetfile
|
|
||||||
|
|
||||||
def write_all(self):
|
|
||||||
#self.write_manifest()
|
|
||||||
self.write_setup()
|
|
||||||
|
|
||||||
def parseargs():
|
|
||||||
basedir = py.path.local(sys.argv[1])
|
|
||||||
if not basedir.check():
|
|
||||||
error("basedir not found: %s" %(basedir,))
|
|
||||||
pydir = basedir.join('py')
|
|
||||||
if not pydir.check():
|
|
||||||
error("no 'py' directory found in: %s" %(pydir,))
|
|
||||||
actualpydir = py.path.local(py.__file__).dirpath()
|
|
||||||
if pydir != actualpydir:
|
|
||||||
error("package dir conflict, %s != %s" %(pydir, actualpydir))
|
|
||||||
return basedir
|
|
||||||
|
|
||||||
def main(basedir=None):
|
|
||||||
if basedir is None:
|
|
||||||
basedir = parseargs()
|
|
||||||
writer = SetupWriter(basedir, py, setuptools=True)
|
|
||||||
writer.write_all()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -1,26 +0,0 @@
|
||||||
import os, sys, subprocess, urllib
|
|
||||||
|
|
||||||
BUILDNAME=os.environ.get('BUILD_NUMBER', "1")
|
|
||||||
|
|
||||||
def call(*args):
|
|
||||||
ret = subprocess.call(list(args))
|
|
||||||
assert ret == 0
|
|
||||||
|
|
||||||
def bincall(*args):
|
|
||||||
args = list(args)
|
|
||||||
args[0] = os.path.join(BIN, args[0])
|
|
||||||
call(*args)
|
|
||||||
|
|
||||||
call("virtualenv", os.path.abspath(BUILDNAME), '--no-site-packages')
|
|
||||||
BIN=os.path.abspath(os.path.join(BUILDNAME, 'bin'))
|
|
||||||
if not os.path.exists(BIN):
|
|
||||||
BIN=os.path.abspath(os.path.join(BUILDNAME, 'Scripts'))
|
|
||||||
assert os.path.exists(BIN)
|
|
||||||
|
|
||||||
PYTHON=os.path.join(BIN, 'python')
|
|
||||||
bincall("python", "setup.py", "develop", "-q")
|
|
||||||
bincall("pip", "install", "-r", "testing/pip-reqs1.txt",
|
|
||||||
"-q", "--download-cache=download")
|
|
||||||
bincall("py.test", "--ignore", BUILDNAME,
|
|
||||||
"--xml=junit.xml",
|
|
||||||
"--report=skipped", "--runslowtest", *sys.argv[1:])
|
|
|
@ -1,301 +0,0 @@
|
||||||
|
|
||||||
import os, sys
|
|
||||||
WIDTH = 75
|
|
||||||
|
|
||||||
plugins = [
|
|
||||||
('advanced python testing',
|
|
||||||
'skipping mark pdb figleaf '
|
|
||||||
'monkeypatch coverage cov capture capturelog recwarn tmpdir',),
|
|
||||||
('distributed testing, CI and deployment',
|
|
||||||
'xdist pastebin junitxml resultlog genscript',),
|
|
||||||
('testing domains and conventions codecheckers',
|
|
||||||
'oejskit django unittest nose doctest restdoc'),
|
|
||||||
('internal, debugging, help functionality',
|
|
||||||
'helpconfig terminal hooklog')
|
|
||||||
#('internal plugins / core functionality',
|
|
||||||
# #'runner execnetcleanup # pytester',
|
|
||||||
# 'runner execnetcleanup' # pytester',
|
|
||||||
#)
|
|
||||||
]
|
|
||||||
|
|
||||||
externals = {
|
|
||||||
'oejskit': "run javascript tests in real life browsers",
|
|
||||||
'xdist': None,
|
|
||||||
'figleaf': None,
|
|
||||||
'capturelog': None,
|
|
||||||
'coverage': None,
|
|
||||||
'cov': None,
|
|
||||||
'codecheckers': None,
|
|
||||||
'django': "for testing django applications",
|
|
||||||
}
|
|
||||||
|
|
||||||
def warn(*args):
|
|
||||||
msg = " ".join(map(str, args))
|
|
||||||
print >>sys.stderr, "WARN:", msg
|
|
||||||
|
|
||||||
class RestWriter:
|
|
||||||
_all_links = {}
|
|
||||||
|
|
||||||
def __init__(self, target):
|
|
||||||
self.target = py.path.local(target)
|
|
||||||
self.links = []
|
|
||||||
|
|
||||||
def _getmsg(self, args):
|
|
||||||
return " ".join(map(str, args))
|
|
||||||
|
|
||||||
def Print(self, *args, **kwargs):
|
|
||||||
msg = self._getmsg(args)
|
|
||||||
if 'indent' in kwargs:
|
|
||||||
indent = kwargs['indent'] * " "
|
|
||||||
lines = [(indent + x) for x in msg.split("\n")]
|
|
||||||
msg = "\n".join(lines)
|
|
||||||
self.out.write(msg)
|
|
||||||
if not msg or msg[-1] != "\n":
|
|
||||||
self.out.write("\n")
|
|
||||||
self.out.flush()
|
|
||||||
|
|
||||||
def sourcecode(self, source):
|
|
||||||
lines = str(source).split("\n")
|
|
||||||
self.Print(".. sourcecode:: python")
|
|
||||||
self.Print()
|
|
||||||
for line in lines:
|
|
||||||
self.Print(" ", line)
|
|
||||||
|
|
||||||
def _sep(self, separator, args):
|
|
||||||
msg = self._getmsg(args)
|
|
||||||
sep = len(msg) * separator
|
|
||||||
self.Print()
|
|
||||||
self.Print(msg)
|
|
||||||
self.Print(sep)
|
|
||||||
self.Print()
|
|
||||||
|
|
||||||
|
|
||||||
def h1(self, *args):
|
|
||||||
self._sep('=', args)
|
|
||||||
|
|
||||||
def h2(self, *args):
|
|
||||||
self._sep('-', args)
|
|
||||||
|
|
||||||
def h3(self, *args):
|
|
||||||
self._sep('+', args)
|
|
||||||
|
|
||||||
def li(self, *args):
|
|
||||||
msg = self._getmsg(args)
|
|
||||||
sep = "* %s" %(msg)
|
|
||||||
self.Print(sep)
|
|
||||||
|
|
||||||
def dt(self, term):
|
|
||||||
self.Print("``%s``" % term)
|
|
||||||
|
|
||||||
def dd(self, doc):
|
|
||||||
self.Print(doc, indent=4)
|
|
||||||
|
|
||||||
def para(self, *args):
|
|
||||||
msg = self._getmsg(args)
|
|
||||||
self.Print(msg)
|
|
||||||
|
|
||||||
def add_internal_link(self, name, path):
|
|
||||||
relpath = path.new(ext=".html").relto(self.target.dirpath())
|
|
||||||
self.links.append((name, relpath))
|
|
||||||
|
|
||||||
def write_links(self):
|
|
||||||
self.Print()
|
|
||||||
self.Print(".. include:: links.txt")
|
|
||||||
for link in self.links:
|
|
||||||
key = link[0]
|
|
||||||
if key in self._all_links:
|
|
||||||
assert self._all_links[key] == link[1], (key, link[1])
|
|
||||||
else:
|
|
||||||
self._all_links[key] = link[1]
|
|
||||||
|
|
||||||
def write_all_links(cls, linkpath):
|
|
||||||
p = linkpath.new(basename="links.txt")
|
|
||||||
p_writer = RestWriter(p)
|
|
||||||
p_writer.out = p_writer.target.open("w")
|
|
||||||
for name, value in cls._all_links.items():
|
|
||||||
p_writer.Print(".. _`%s`: %s" % (name, value))
|
|
||||||
p_writer.out.close()
|
|
||||||
del p_writer.out
|
|
||||||
write_all_links = classmethod(write_all_links)
|
|
||||||
|
|
||||||
def make(self, **kwargs):
|
|
||||||
self.out = self.target.open("w")
|
|
||||||
self.makerest(**kwargs)
|
|
||||||
self.write_links()
|
|
||||||
|
|
||||||
self.out.close()
|
|
||||||
print "wrote", self.target
|
|
||||||
del self.out
|
|
||||||
|
|
||||||
class PluginOverview(RestWriter):
|
|
||||||
def makerest(self, config):
|
|
||||||
plugindir = py._pydir.join('plugin')
|
|
||||||
for cat, specs in plugins:
|
|
||||||
pluginlist = specs.split()
|
|
||||||
self.h1(cat)
|
|
||||||
for name in pluginlist:
|
|
||||||
oneliner = externals.get(name, None)
|
|
||||||
docpath = self.target.dirpath(name).new(ext=".txt")
|
|
||||||
if oneliner is not None:
|
|
||||||
htmlpath = docpath.new(ext='.html')
|
|
||||||
self.para("%s_ (external) %s" %(name, oneliner))
|
|
||||||
self.add_internal_link(name, htmlpath)
|
|
||||||
else:
|
|
||||||
doc = PluginDoc(docpath)
|
|
||||||
doc.make(config=config, name=name)
|
|
||||||
self.add_internal_link(name, doc.target)
|
|
||||||
if name in externals:
|
|
||||||
self.para("%s_ (external) %s" %(name, doc.oneliner))
|
|
||||||
else:
|
|
||||||
self.para("%s_ %s" %(name, doc.oneliner))
|
|
||||||
self.Print()
|
|
||||||
|
|
||||||
class HookSpec(RestWriter):
|
|
||||||
def makerest(self, config):
|
|
||||||
for module in config.pluginmanager.hook._hookspecs:
|
|
||||||
source = py.code.Source(module)
|
|
||||||
self.h1("hook specification sourcecode")
|
|
||||||
self.sourcecode(source)
|
|
||||||
|
|
||||||
class PluginDoc(RestWriter):
|
|
||||||
def makerest(self, config, name):
|
|
||||||
config.pluginmanager.import_plugin(name)
|
|
||||||
plugin = config.pluginmanager.getplugin(name)
|
|
||||||
assert plugin is not None, plugin
|
|
||||||
print plugin
|
|
||||||
doc = plugin.__doc__.strip()
|
|
||||||
i = doc.find("\n")
|
|
||||||
if i == -1:
|
|
||||||
oneliner = doc
|
|
||||||
moduledoc = ""
|
|
||||||
else:
|
|
||||||
oneliner = doc[:i].strip()
|
|
||||||
moduledoc = doc[i+1:].strip()
|
|
||||||
|
|
||||||
self.name = oneliner # plugin.__name__.split(".")[-1]
|
|
||||||
self.oneliner = oneliner
|
|
||||||
self.moduledoc = moduledoc
|
|
||||||
|
|
||||||
#self.h1("%s plugin" % self.name) # : %s" %(self.name, self.oneliner))
|
|
||||||
self.h1(oneliner)
|
|
||||||
#self.Print(self.oneliner)
|
|
||||||
self.Print()
|
|
||||||
self.Print(".. contents::")
|
|
||||||
self.Print(" :local:")
|
|
||||||
self.Print()
|
|
||||||
|
|
||||||
self.Print(moduledoc)
|
|
||||||
|
|
||||||
self.emit_funcargs(plugin)
|
|
||||||
self.emit_options(plugin)
|
|
||||||
if name not in externals:
|
|
||||||
self.emit_source(plugin, config.hg_changeset)
|
|
||||||
#self.sourcelink = (purename,
|
|
||||||
# "http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/" +
|
|
||||||
# purename + ".py")
|
|
||||||
#
|
|
||||||
def emit_source(self, plugin, hg_changeset):
|
|
||||||
basename = py.path.local(plugin.__file__).basename
|
|
||||||
if basename.endswith("pyc"):
|
|
||||||
basename = basename[:-1]
|
|
||||||
#self.para("`%s`_ source code" % basename)
|
|
||||||
#self.links.append((basename,
|
|
||||||
# "http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/" +
|
|
||||||
# basename))
|
|
||||||
self.h1("Start improving this plugin in 30 seconds")
|
|
||||||
self.para(py.code.Source("""
|
|
||||||
1. Download `%s`_ plugin source code
|
|
||||||
2. put it somewhere as ``%s`` into your import path
|
|
||||||
3. a subsequent ``py.test`` run will use your local version
|
|
||||||
|
|
||||||
Checkout customize_, other plugins_ or `get in contact`_.
|
|
||||||
""" % (basename, basename)))
|
|
||||||
# your work appreciated if you offer back your version. In this case
|
|
||||||
# it probably makes sense if you `checkout the py.test
|
|
||||||
# development version`_ and apply your changes to the plugin
|
|
||||||
# version in there.
|
|
||||||
#self.links.append((basename,
|
|
||||||
# "http://bitbucket.org/hpk42/py-trunk/raw/%s/"
|
|
||||||
# "py/test/plugin/%s" %(hg_changeset, basename)))
|
|
||||||
self.links.append((basename,
|
|
||||||
"http://bitbucket.org/hpk42/py-trunk/raw/%s/"
|
|
||||||
"py/_plugin/%s" %(pyversion, basename)))
|
|
||||||
self.links.append(('customize', '../customize.html'))
|
|
||||||
self.links.append(('plugins', 'index.html'))
|
|
||||||
self.links.append(('get in contact', '../../contact.html'))
|
|
||||||
self.links.append(('checkout the py.test development version',
|
|
||||||
'../../install.html#checkout'))
|
|
||||||
|
|
||||||
if 0: # this breaks the page layout and makes large doc files
|
|
||||||
#self.h2("plugin source code")
|
|
||||||
self.Print()
|
|
||||||
self.para("For your convenience here is also an inlined version "
|
|
||||||
"of ``%s``:" %basename)
|
|
||||||
#self(or copy-paste from below)
|
|
||||||
self.Print()
|
|
||||||
self.sourcecode(py.code.Source(plugin))
|
|
||||||
|
|
||||||
def emit_funcargs(self, plugin):
|
|
||||||
funcargfuncs = []
|
|
||||||
prefix = "pytest_funcarg__"
|
|
||||||
for name in vars(plugin):
|
|
||||||
if name.startswith(prefix):
|
|
||||||
funcargfuncs.append(getattr(plugin, name))
|
|
||||||
if not funcargfuncs:
|
|
||||||
return
|
|
||||||
for func in funcargfuncs:
|
|
||||||
argname = func.__name__[len(prefix):]
|
|
||||||
self.Print()
|
|
||||||
self.Print(".. _`%s funcarg`:" % argname)
|
|
||||||
self.Print()
|
|
||||||
self.h2("the %r test function argument" % argname)
|
|
||||||
if func.__doc__:
|
|
||||||
doclines = func.__doc__.split("\n")
|
|
||||||
source = py.code.Source("\n".join(doclines[1:]))
|
|
||||||
source.lines.insert(0, doclines[0])
|
|
||||||
self.para(str(source))
|
|
||||||
else:
|
|
||||||
self.para("XXX missing docstring")
|
|
||||||
warn("missing docstring", func)
|
|
||||||
|
|
||||||
def emit_options(self, plugin):
|
|
||||||
from pytest.parseopt import Parser
|
|
||||||
options = []
|
|
||||||
parser = Parser(processopt=options.append)
|
|
||||||
if hasattr(plugin, 'pytest_addoption'):
|
|
||||||
plugin.pytest_addoption(parser)
|
|
||||||
if not options:
|
|
||||||
return
|
|
||||||
self.h2("command line options")
|
|
||||||
self.Print()
|
|
||||||
formatter = py.std.optparse.IndentedHelpFormatter()
|
|
||||||
for opt in options:
|
|
||||||
switches = formatter.format_option_strings(opt)
|
|
||||||
self.Print("``%s``" % switches)
|
|
||||||
self.Print(opt.help, indent=4)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if os.path.exists("py"):
|
|
||||||
sys.path.insert(0, os.getcwd())
|
|
||||||
import py
|
|
||||||
_config = py.test.config
|
|
||||||
_config.parse([])
|
|
||||||
_config.pluginmanager.do_configure(_config)
|
|
||||||
|
|
||||||
pydir = py.path.local(py.__file__).dirpath()
|
|
||||||
pyversion = py.version
|
|
||||||
|
|
||||||
cmd = "hg tip --template '{node}'"
|
|
||||||
old = pydir.dirpath().chdir()
|
|
||||||
_config.hg_changeset = py.process.cmdexec(cmd).strip()
|
|
||||||
|
|
||||||
testdir = pydir.dirpath("doc", 'test')
|
|
||||||
|
|
||||||
ov = PluginOverview(testdir.join("plugin", "index.txt"))
|
|
||||||
ov.make(config=_config)
|
|
||||||
|
|
||||||
ov = HookSpec(testdir.join("plugin", "hookspec.txt"))
|
|
||||||
ov.make(config=_config)
|
|
||||||
|
|
||||||
RestWriter.write_all_links(testdir.join("plugin", "links.txt"))
|
|
||||||
|
|
|
@ -1,228 +0,0 @@
|
||||||
import py
|
|
||||||
import subprocess
|
|
||||||
import os, sys
|
|
||||||
|
|
||||||
execnet = py.test.importorskip("execnet")
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# experimental funcargs for venv/install-tests
|
|
||||||
#
|
|
||||||
|
|
||||||
pytest_plugins = 'pytest_pytester',
|
|
||||||
|
|
||||||
def pytest_funcarg__venv(request):
|
|
||||||
p = request.config.mktemp(request.function.__name__, numbered=True)
|
|
||||||
venv = VirtualEnv(str(p))
|
|
||||||
return venv
|
|
||||||
|
|
||||||
def pytest_funcarg__py_setup(request):
|
|
||||||
testdir = request.getfuncargvalue('testdir')
|
|
||||||
rootdir = py.path.local(py.__file__).dirpath().dirpath()
|
|
||||||
setup = rootdir.join('setup.py')
|
|
||||||
if not setup.check():
|
|
||||||
py.test.skip("not found: %r" % setup)
|
|
||||||
return SetupBuilder(setup, testdir.tmpdir)
|
|
||||||
|
|
||||||
class SetupBuilder:
|
|
||||||
def __init__(self, setup_path, tmpdir):
|
|
||||||
self.setup_path = setup_path
|
|
||||||
self.tmpdir = tmpdir
|
|
||||||
assert setup_path.check()
|
|
||||||
|
|
||||||
def make_sdist(self, destdir=None):
|
|
||||||
temp = self.tmpdir.mkdir('dist')
|
|
||||||
args = ['python', 'setup.py', 'sdist', '--dist-dir', str(temp)]
|
|
||||||
old = self.setup_path.dirpath().chdir()
|
|
||||||
try:
|
|
||||||
subcall(args)
|
|
||||||
finally:
|
|
||||||
old.chdir()
|
|
||||||
l = temp.listdir('py-*')
|
|
||||||
assert len(l) == 1
|
|
||||||
sdist = l[0]
|
|
||||||
if destdir is None:
|
|
||||||
destdir = self.setup_path.dirpath('build')
|
|
||||||
assert destdir.check()
|
|
||||||
else:
|
|
||||||
destdir = py.path.local(destdir)
|
|
||||||
target = destdir.join(sdist.basename)
|
|
||||||
sdist.copy(target)
|
|
||||||
return target
|
|
||||||
|
|
||||||
def subcall(args):
|
|
||||||
if hasattr(subprocess, 'check_call'):
|
|
||||||
subprocess.check_call(args)
|
|
||||||
else:
|
|
||||||
subprocess.call(args)
|
|
||||||
# code taken from Ronny Pfannenschmidt's virtualenvmanager
|
|
||||||
|
|
||||||
class VirtualEnv(object):
|
|
||||||
def __init__(self, path):
|
|
||||||
#XXX: supply the python executable
|
|
||||||
self.path = path
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<VirtualEnv at %r>" %(self.path)
|
|
||||||
|
|
||||||
def _cmd(self, name):
|
|
||||||
if sys.platform == "win32":
|
|
||||||
return os.path.join(self.path, 'Scripts', name)
|
|
||||||
else:
|
|
||||||
return os.path.join(self.path, 'bin', name)
|
|
||||||
|
|
||||||
def ensure(self):
|
|
||||||
if not os.path.exists(self._cmd('python')):
|
|
||||||
self.create()
|
|
||||||
|
|
||||||
def create(self, sitepackages=False):
|
|
||||||
args = ['virtualenv', self.path]
|
|
||||||
if not sitepackages:
|
|
||||||
args.append('--no-site-packages')
|
|
||||||
subcall(args)
|
|
||||||
|
|
||||||
def makegateway(self):
|
|
||||||
python = self._cmd('python')
|
|
||||||
return execnet.makegateway("popen//python=%s" %(python,))
|
|
||||||
|
|
||||||
def pcall(self, cmd, *args, **kw):
|
|
||||||
self.ensure()
|
|
||||||
return subprocess.call([
|
|
||||||
self._cmd(cmd)
|
|
||||||
] + list(args),
|
|
||||||
**kw)
|
|
||||||
|
|
||||||
def pytest_getouterr(self, *args):
|
|
||||||
self.ensure()
|
|
||||||
args = [self._cmd("py.test")] + list(args)
|
|
||||||
popen = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
||||||
out, err = popen.communicate()
|
|
||||||
return out
|
|
||||||
|
|
||||||
def setup_develop(self):
|
|
||||||
self.ensure()
|
|
||||||
return self.pcall("python", "setup.py", "develop")
|
|
||||||
|
|
||||||
def easy_install(self, *packages, **kw):
|
|
||||||
args = []
|
|
||||||
if 'index' in kw:
|
|
||||||
index = kw['index']
|
|
||||||
if isinstance(index, (list, tuple)):
|
|
||||||
for i in index:
|
|
||||||
args.extend(['-i', i])
|
|
||||||
else:
|
|
||||||
args.extend(['-i', index])
|
|
||||||
|
|
||||||
args.extend(packages)
|
|
||||||
self.pcall('easy_install', *args)
|
|
||||||
|
|
||||||
|
|
||||||
def test_make_sdist_and_run_it(py_setup, venv):
|
|
||||||
sdist = py_setup.make_sdist(venv.path)
|
|
||||||
venv.easy_install(str(sdist))
|
|
||||||
gw = venv.makegateway()
|
|
||||||
ch = gw.remote_exec("import py ; channel.send(py.__version__)")
|
|
||||||
version = ch.receive()
|
|
||||||
assert version == py.__version__
|
|
||||||
|
|
||||||
def test_plugin_setuptools_entry_point_integration(py_setup, venv, tmpdir):
|
|
||||||
sdist = py_setup.make_sdist(venv.path)
|
|
||||||
venv.easy_install(str(sdist))
|
|
||||||
# create a sample plugin
|
|
||||||
basedir = tmpdir.mkdir("testplugin")
|
|
||||||
basedir.join("setup.py").write("""if 1:
|
|
||||||
from setuptools import setup
|
|
||||||
setup(name="testplugin",
|
|
||||||
entry_points = {'pytest11': ['testplugin=tp1']},
|
|
||||||
py_modules = ['tp1'],
|
|
||||||
)
|
|
||||||
""")
|
|
||||||
basedir.join("tp1.py").write(py.code.Source("""
|
|
||||||
def pytest_addoption(parser):
|
|
||||||
parser.addoption("--testpluginopt", action="store_true")
|
|
||||||
"""))
|
|
||||||
basedir.chdir()
|
|
||||||
print ("created sample plugin in %s" %basedir)
|
|
||||||
venv.setup_develop()
|
|
||||||
out = venv.pytest_getouterr("-h")
|
|
||||||
assert "testpluginopt" in out
|
|
||||||
|
|
||||||
def test_cmdline_entrypoints(monkeypatch):
|
|
||||||
monkeypatch.syspath_prepend(py.path.local(__file__).dirpath().dirpath())
|
|
||||||
from setup import cmdline_entrypoints
|
|
||||||
versioned_scripts = ['py.test', 'py.which']
|
|
||||||
unversioned_scripts = versioned_scripts + [ 'py.cleanup',
|
|
||||||
'py.convert_unittest', 'py.countloc', 'py.lookup', 'py.svnwcrevert']
|
|
||||||
for ver in [(2,4,0), (2,5,0), (2,6,0), (2,7,0), (3,0,1), (3,1,1)]:
|
|
||||||
for platform in ('posix', 'win32'):
|
|
||||||
points = cmdline_entrypoints(ver, "posix", 'python')
|
|
||||||
for script in versioned_scripts:
|
|
||||||
script_ver = script + "-%s.%s" % ver[:2]
|
|
||||||
assert script_ver in points
|
|
||||||
for script in unversioned_scripts:
|
|
||||||
assert script in points
|
|
||||||
points = cmdline_entrypoints((2,5,1), "java1.6.123", 'jython')
|
|
||||||
for script in versioned_scripts:
|
|
||||||
expected = "%s-jython" % script
|
|
||||||
assert expected in points
|
|
||||||
for script in unversioned_scripts:
|
|
||||||
assert script in points
|
|
||||||
|
|
||||||
points = cmdline_entrypoints((2,5,1), "xyz", 'pypy-c-XYZ')
|
|
||||||
for script in versioned_scripts:
|
|
||||||
expected = "%s-pypy-c-XYZ" % script
|
|
||||||
assert expected in points
|
|
||||||
for script in unversioned_scripts:
|
|
||||||
assert script in points
|
|
||||||
|
|
||||||
def test_slave_popen_needs_no_pylib(testdir, venv, pytestconfig):
|
|
||||||
pytestconfig.pluginmanager.skipifmissing("xdist")
|
|
||||||
venv.ensure()
|
|
||||||
#xxx execnet optimizes popen
|
|
||||||
#ch = venv.makegateway().remote_exec("import execnet")
|
|
||||||
#py.test.raises(ch.RemoteError, ch.waitclose)
|
|
||||||
python = venv._cmd("python")
|
|
||||||
p = testdir.makepyfile("""
|
|
||||||
import py
|
|
||||||
def test_func():
|
|
||||||
pass
|
|
||||||
""")
|
|
||||||
result = testdir.runpytest(p, '--rsyncdir=%s' % str(p),
|
|
||||||
'--dist=each', '--tx=popen//python=%s' % python)
|
|
||||||
result.stdout.fnmatch_lines([
|
|
||||||
"*1 passed*"
|
|
||||||
])
|
|
||||||
|
|
||||||
def test_slave_needs_no_execnet(testdir, sshhost, pytestconfig):
|
|
||||||
pytestconfig.pluginmanager.skipifmissing("xdist")
|
|
||||||
xspec = "ssh=%s" % sshhost
|
|
||||||
gw = execnet.makegateway("ssh=%s" % sshhost)
|
|
||||||
ch = gw.remote_exec("""
|
|
||||||
import os, subprocess
|
|
||||||
subprocess.call(["virtualenv", "--no-site-packages", "subdir"])
|
|
||||||
channel.send(os.path.join(os.path.abspath("subdir"), 'bin', 'python'))
|
|
||||||
channel.send(os.path.join(os.path.abspath("subdir")))
|
|
||||||
""")
|
|
||||||
try:
|
|
||||||
path = ch.receive()
|
|
||||||
chdir = ch.receive()
|
|
||||||
except ch.RemoteError:
|
|
||||||
e = sys.exc_info()[1]
|
|
||||||
py.test.skip("could not prepare ssh slave:%s" % str(e))
|
|
||||||
gw.exit()
|
|
||||||
newspec = "%s//python=%s//chdir=%s" % (xspec, path, chdir)
|
|
||||||
gw = execnet.makegateway(newspec)
|
|
||||||
ch = gw.remote_exec("import execnet")
|
|
||||||
py.test.raises(ch.RemoteError, ch.waitclose)
|
|
||||||
gw.exit()
|
|
||||||
|
|
||||||
p = testdir.makepyfile("""
|
|
||||||
import py
|
|
||||||
def test_func():
|
|
||||||
pass
|
|
||||||
""")
|
|
||||||
result = testdir.runpytest(p, '--rsyncdir=%s' % str(p),
|
|
||||||
'--dist=each', '--tx=%s' % newspec)
|
|
||||||
result.stdout.fnmatch_lines([
|
|
||||||
"*1 passed*"
|
|
||||||
])
|
|
Loading…
Reference in New Issue