Commit 86395186 authored by Sebastian Ramacher's avatar Sebastian Ramacher

Imported Upstream version 0.9.0

parent 1dcf4b17
Metadata-Version: 1.0
Name: py
Version: 0.9.0
Summary: py lib: agile development and test support library
Home-page: http://codespeak.net/py
Author: holger krekel, Carl Friedrich Bolz, Guido Wesdorp, Maciej Fijalkowski, Armin Rigo & others
Author-email: py-dev@codespeak.net
License: MIT license
Download-URL: http://codespeak.net/download/py/py-0.9.0.tar.gz
Description:
the py lib is a development support library featuring
py.test, ad-hoc distributed execution, micro-threads
and svn abstractions.
Platform: unix
Platform: linux
Platform: cygwin
......@@ -8,6 +8,9 @@ copyrighted by one or more of the following people and organizations:
Holger Krekel <hpk@trillke.net>
merlinux GmbH, Germany <office@merlinux.de>
Armin Rigo <arigo@tunes.org>
Carl Friedrich Bolz <cfbolz@merlinux.de>
Maciek Fijalkowski <fijal@genesilico.pl>
Guido Wesdorp <guido@merlinux.de>
Jan Balster <jan@balster.info>
Contributors include::
......
"""\
the py lib is a development support library featuring
py.test, an interactive testing tool which supports
unit-testing with practically no boilerplate.
"""
the py lib is a development support library featuring
py.test, ad-hoc distributed execution, micro-threads
and svn abstractions.
"""
from initpkg import initpkg
version = "0.9.0"
initpkg(__name__,
description = "py.test and the py lib",
revision = int('$LastChangedRevision: 26999 $'.split(':')[1][:-1]),
lastchangedate = '$LastChangedDate: 2006-05-09 12:38:55 -0300 (Tue, 09 May 2006) $',
version = "0.8.0-alpha2",
description = "py lib: agile development and test support library",
revision = int('$LastChangedRevision: 38799 $'.split(':')[1][:-1]),
lastchangedate = '$LastChangedDate: 2007-02-14 12:10:40 +0100 (Wed, 14 Feb 2007) $',
version = version,
url = "http://codespeak.net/py",
download_url = "http://codespeak.net/download/py/py-0.8.0-alpha2.tar.gz",
download_url = "http://codespeak.net/download/py/py-%s.tar.gz" %(version,),
license = "MIT license",
platforms = ['unix', 'linux', 'cygwin'],
author = "holger krekel & others",
author_email = "hpk@merlinux.de",
author = "holger krekel, Carl Friedrich Bolz, Guido Wesdorp, Maciej Fijalkowski, Armin Rigo & others",
author_email = "py-dev@codespeak.net",
long_description = globals()['__doc__'],
# EXPORTED API
exportdefs = {
'_dist.setup' : ('./misc/_dist.py', 'setup'),
# helpers for use from test functions or collectors
'test.__doc__' : ('./test/__init__.py', '__doc__'),
'test.raises' : ('./test/raises.py', 'raises'),
'test.deprecated_call' : ('./test/deprecate.py', 'deprecated_call'),
'test.skip' : ('./test/item.py', 'skip'),
'test.fail' : ('./test/item.py', 'fail'),
'test.exit' : ('./test/session.py', 'exit'),
'test.compat.TestCase' : ('./test/compat.py', 'TestCase'),
# configuration/initialization related test api
'test.Config' : ('./test/config.py', 'Config'),
'test.config' : ('./test/config.py', 'config_per_process'),
'test.ensuretemp' : ('./test/config.py', 'ensuretemp'),
'test.cmdline.main' : ('./test/cmdline.py', 'main'),
# for customization of collecting/running tests
'test.Session' : ('./test/session.py', 'Session'),
'test.TerminalSession' : ('./test/terminal/terminal.py', 'TerminalSession'),
'test.TkinterSession' : ('./test/tkinter/tksession.py', 'TkSession'),
'test.collect.Collector' : ('./test/collect.py', 'Collector'),
'test.collect.Directory' : ('./test/collect.py', 'Directory'),
'test.collect.Module' : ('./test/collect.py', 'Module'),
'test.collect.DoctestFile' : ('./test/collect.py', 'DoctestFile'),
'test.collect.Class' : ('./test/collect.py', 'Class'),
'test.collect.Instance' : ('./test/collect.py', 'Instance'),
'test.collect.Generator' : ('./test/collect.py', 'Generator'),
'test.Item' : ('./test/item.py', 'Item'),
'test.Function' : ('./test/item.py', 'Function'),
'test.collect.Item' : ('./test/item.py', 'Item'),
'test.collect.Function' : ('./test/item.py', 'Function'),
# thread related API (still in early design phase)
'_thread.WorkerPool' : ('./thread/pool.py', 'WorkerPool'),
......@@ -55,26 +54,27 @@ initpkg(__name__,
# hook into the top-level standard library
'std' : ('./misc/std.py', 'std'),
'process.__doc__' : ('./process/__init__.py', '__doc__'),
'process.cmdexec' : ('./process/cmdexec.py', 'cmdexec'),
# path implementations
# path implementation
'path.__doc__' : ('./path/__init__.py', '__doc__'),
'path.svnwc' : ('./path/svn/wccommand.py', 'SvnWCCommandPath'),
'path.svnurl' : ('./path/svn/urlcommand.py', 'SvnCommandPath'),
'path.local' : ('./path/local/local.py', 'LocalPath'),
'path.extpy' : ('./path/extpy/extpy.py', 'Extpy'),
'path.checker' : ('./path/common.py', 'checker'), # deprecated
# some nice slightly magic APIs
'magic.__doc__' : ('./magic/__init__.py', '__doc__'),
'magic.greenlet' : ('./magic/greenlet.py', 'greenlet'),
'magic.invoke' : ('./magic/invoke.py', 'invoke'),
'magic.revoke' : ('./magic/invoke.py', 'revoke'),
'magic.patch' : ('./magic/patch.py', 'patch'),
'magic.revert' : ('./magic/patch.py', 'revert'),
'magic.autopath' : ('./magic/autopath.py', 'autopath'),
'magic.View' : ('./magic/viewtype.py', 'View'),
'magic.AssertionError' : ('./magic/assertion.py', 'AssertionError'),
# python inspection/code-generation API
'code.__doc__' : ('./code/__init__.py', '__doc__'),
'code.compile' : ('./code/source.py', 'compile_'),
'code.Source' : ('./code/source.py', 'Source'),
'code.Code' : ('./code/code.py', 'Code'),
......@@ -83,30 +83,43 @@ initpkg(__name__,
'code.Traceback' : ('./code/traceback2.py', 'Traceback'),
# backports and additions of builtins
'builtin.__doc__' : ('./builtin/__init__.py', '__doc__'),
'builtin.enumerate' : ('./builtin/enumerate.py', 'enumerate'),
'builtin.reversed' : ('./builtin/reversed.py', 'reversed'),
'builtin.sorted' : ('./builtin/sorted.py', 'sorted'),
'builtin.BaseException' : ('./builtin/exception.py', 'BaseException'),
'builtin.set' : ('./builtin/set.py', 'set'),
'builtin.frozenset' : ('./builtin/set.py', 'frozenset'),
# gateways into remote contexts
'execnet.__doc__' : ('./execnet/__init__.py', '__doc__'),
'execnet.SocketGateway' : ('./execnet/register.py', 'SocketGateway'),
'execnet.PopenGateway' : ('./execnet/register.py', 'PopenGateway'),
'execnet.SshGateway' : ('./execnet/register.py', 'SshGateway'),
# execnet scripts
'execnet.RSync' : ('./execnet/rsync.py', 'RSync'),
# input-output helping
'io.__doc__' : ('./io/__init__.py', '__doc__'),
'io.dupfile' : ('./io/dupfile.py', 'dupfile'),
'io.FDCapture' : ('./io/capture.py', 'FDCapture'),
'io.OutErrCapture' : ('./io/capture.py', 'OutErrCapture'),
'io.callcapture' : ('./io/capture.py', 'callcapture'),
'io.FDCapture' : ('./io/fdcapture.py', 'FDCapture'),
'io.StdCapture' : ('./io/stdcapture.py', 'StdCapture'),
'io.StdCaptureFD' : ('./io/stdcapture.py', 'StdCaptureFD'),
# error module, defining all errno's as Classes
'error' : ('./misc/error.py', 'error'),
# small and mean xml/html generation
'xml.__doc__' : ('./xmlobj/__init__.py', '__doc__'),
'xml.html' : ('./xmlobj/html.py', 'html'),
'xml.Tag' : ('./xmlobj/xml.py', 'Tag'),
'xml.raw' : ('./xmlobj/xml.py', 'raw'),
'xml.Namespace' : ('./xmlobj/xml.py', 'Namespace'),
'xml.escape' : ('./xmlobj/misc.py', 'escape'),
# logging API ('producers' and 'consumers' connected via keywords)
'log.__doc__' : ('./log/__init__.py', '__doc__'),
'log.Producer' : ('./log/producer.py', 'Producer'),
'log.default' : ('./log/producer.py', 'default'),
'log._getstate' : ('./log/producer.py', '_getstate'),
......@@ -118,8 +131,11 @@ initpkg(__name__,
'log.Syslog' : ('./log/consumer.py', 'Syslog'),
'log.get' : ('./log/logger.py', 'get'),
# compatibility modules (taken from 2.4.1)
# compatibility modules (taken from 2.4.4)
'compat.__doc__' : ('./compat/__init__.py', '__doc__'),
'compat.doctest' : ('./compat/doctest.py', '*'),
'compat.optparse' : ('./compat/optparse.py', '*'),
'compat.textwrap' : ('./compat/textwrap.py', '*'),
'compat.subprocess' : ('./compat/subprocess.py', '*'),
})
function showhideel(el) {
/* show or hide the element
sets the value of el.style.display to 'none' or 'block' depending
on the current value
*/
if (el.style.display == 'none') {
el.style.display = 'block';
} else {
el.style.display = 'none';
};
};
function getnextsibling(el) {
/* return next non-text sibling (or null) */
var node = el.nextSibling;
while (node && node.nodeType != 1) {
node = node.nextSibling;
};
return node;
};
function loadloc() {
/* load iframe content using # part of the url */
var loc = document.location.toString();
if (loc.indexOf('#') == -1) {
return;
};
var chunks = loc.split('#');
var anchor = chunks[chunks.length - 1];
var iframe = document.getElementsByTagName('iframe')[0];
iframe.src = anchor;
};
""" run 'py.test --apigen=<this script>' to get documentation exported
"""
import os
import py
import sys
from py.__.apigen import htmlgen
from py.__.apigen import linker
from py.__.apigen import project
from py.__.apigen.tracer.docstorage import pkg_to_dict
from py.__.doc.conftest import get_apigenpath
from layout import LayoutPage
def get_documentable_items_pkgdir(pkgdir):
""" get all documentable items from an initpkg pkgdir
this is a generic implementation, import as 'get_documentable_items'
from your module when using initpkg to get all public stuff in the
package documented
"""
sys.path.insert(0, str(pkgdir.dirpath()))
rootmod = __import__(pkgdir.basename)
d = pkg_to_dict(rootmod)
return pkgdir.basename, d
def get_documentable_items(pkgdir):
pkgname, pkgdict = get_documentable_items_pkgdir(pkgdir)
from py.__.execnet.channel import Channel
pkgdict['execnet.Channel'] = Channel
Channel.__apigen_hide_from_nav__ = True
return pkgname, pkgdict
def build(pkgdir, dsa, capture):
# create a linker (link database) for cross-linking
l = linker.TempLinker()
# create a project.Project instance to contain the LayoutPage instances
proj = project.Project()
# output dir
from py.__.conftest import option
targetdir = get_apigenpath()
targetdir.ensure(dir=True)
# find out what to build
all_names = dsa._get_names(filter=lambda x, y: True)
namespace_tree = htmlgen.create_namespace_tree(all_names)
# and build it
apb = htmlgen.ApiPageBuilder(targetdir, l, dsa, pkgdir, namespace_tree,
proj, capture, LayoutPage)
spb = htmlgen.SourcePageBuilder(targetdir, l, pkgdir, proj, capture,
LayoutPage)
apb.build_namespace_pages()
class_names = dsa.get_class_names()
apb.build_class_pages(class_names)
function_names = dsa.get_function_names()
apb.build_function_pages(function_names)
spb.build_pages(pkgdir)
l.replace_dirpath(targetdir)
import py
Option = py.test.config.Option
option = py.test.config.addoptions("apigen test options",
Option('', '--webcheck',
action="store_true", dest="webcheck", default=False,
help="run XHTML validation tests"
),
)
import py
html = py.xml.html
# HTML related stuff
class H(html):
class Content(html.div):
def __init__(self, *args):
super(H.Content, self).__init__(id='apigen-content', *args)
class Description(html.div):
pass
class NamespaceDescription(Description):
pass
class NamespaceItem(html.div):
pass
class NamespaceDef(html.h1):
pass
class ClassDescription(Description):
pass
class ClassDef(html.div):
def __init__(self, classname, bases, docstring, sourcelink,
attrs, methods):
header = H.h1('class %s(' % (classname,))
for i, (name, href) in py.builtin.enumerate(bases):
if i > 0:
header.append(', ')
link = name
if href is not None:
link = H.a(name, href=href)
header.append(H.BaseDescription(link))
header.append('):')
super(H.ClassDef, self).__init__(header)
self.append(H.div(H.Docstring(docstring or
'*no docstring available*'),
sourcelink,
class_='classdoc'))
if attrs:
self.append(H.h2('class attributes and properties:'))
for name, val in attrs:
self.append(H.PropertyDescription(name, val))
if methods:
self.append(H.h2('methods:'))
for methodhtml in methods:
self.append(methodhtml)
class MethodDescription(Description):
pass
class MethodDef(html.h2):
pass
class FunctionDescription(Description):
def __init__(self, localname, argdesc, docstring, valuedesc, csource,
callstack):
infoid = 'info_%s' % (localname.replace('.', '_dot_'),)
docstringid = 'docstring_%s' % (localname.replace('.', '_dot_'),)
fd = H.FunctionDef(localname, argdesc,
onclick=('showhideel('
'document.getElementById("%s")); '
% (infoid,)))
infodiv = H.div(
H.Docstring(docstring or '*no docstring available*',
id=docstringid),
H.FunctionInfo(valuedesc, csource, callstack,
id=infoid, style="display: none"),
class_='funcdocinfo')
super(H.FunctionDescription, self).__init__(fd, infodiv)
class FunctionDef(html.h2):
style = html.Style(cursor='pointer')
def __init__(self, name, argdesc, **kwargs):
class_ = kwargs.pop('class_', 'funcdef')
super(H.FunctionDef, self).__init__('def %s%s:' % (name, argdesc),
class_=class_, **kwargs)
class FunctionInfo(html.div):
def __init__(self, valuedesc, csource, callstack, **kwargs):
super(H.FunctionInfo, self).__init__(valuedesc, H.br(), csource,
callstack, class_='funcinfo',
**kwargs)
class PropertyDescription(html.div):
def __init__(self, name, value):
if type(value) not in [str, unicode]:
value = str(value)
if len(value) > 100:
value = value[:100] + '...'
super(H.PropertyDescription, self).__init__(name, ': ',
H.em(value),
class_='property')
class ParameterDescription(html.div):
pass
class Docstring(html.div):
style = html.Style(white_space='pre', color='#666',
margin_left='1em', margin_bottom='1em')
class Navigation(html.div):
#style = html.Style(min_height='99%', float='left', margin_top='1.2em',
# overflow='auto', width='15em', white_space='nowrap')
pass
class NavigationItem(html.div):
def __init__(self, linker, linkid, name, indent, selected):
href = linker.get_lazyhref(linkid)
super(H.NavigationItem, self).__init__((indent * 2 * u'\xa0'),
H.a(name, href=href))
if selected:
self.attr.class_ = 'selected'
class BaseDescription(html.span):
pass
class SourceSnippet(html.div):
def __init__(self, text, href, sourceels=None):
if sourceels is None:
sourceels = []
link = text
if href:
link = H.a(text, href=href)
super(H.SourceSnippet, self).__init__(
link, H.div(*sourceels))
class PythonSource(Content):
style = html.Style(font_size='0.8em')
def __init__(self, *sourceels):
super(H.PythonSource, self).__init__(
H.div(*sourceels))
class SourceBlock(html.table):
def __init__(self):
tbody = H.tbody()
row = H.tr()
tbody.append(row)
linenocell = H.td(style='width: 1%')
row.append(linenocell)
linecell = H.td()
row.append(linecell)
self.linenotable = lntable = H.table()
self.linenotbody = lntbody = H.tbody()
lntable.append(lntbody)
linenocell.append(lntable)
self.linetable = ltable = H.table()
self.linetbody = ltbody = H.tbody()
ltable.append(ltbody)
linecell.append(ltable)
super(H.SourceBlock, self).__init__(tbody, class_='codeblock')
def add_line(self, lineno, els):
self.linenotbody.append(H.tr(H.td(lineno, class_='lineno')))
self.linetbody.append(H.tr(H.td(H.pre(class_='code', *els),
class_='codecell')))
class NonPythonSource(Content):
def __init__(self, *args):
super(H.NonPythonSource, self).__init__(H.pre(*args))
class DirList(Content):
def __init__(self, dirs, files):
dirs = [H.DirListItem(text, href) for (text, href) in dirs]
files = [H.DirListItem(text, href) for (text, href) in files]
super(H.DirList, self).__init__(
H.h2('directories'), dirs,
H.h2('files'), files,
)
class DirListItem(html.div):
def __init__(self, text, href):
super(H.DirListItem, self).__init__(H.a(text, href=href))
class ValueDescList(html.ul):
def __init__(self, *args, **kwargs):
super(H.ValueDescList, self).__init__(*args, **kwargs)
class ValueDescItem(html.li):
pass
class CallStackDescription(Description):
pass
class CallStackLink(html.div):
def __init__(self, filename, lineno, href):
super(H.CallStackLink, self).__init__(
H.a("stack trace %s - line %s" % (filename, lineno),
href=href))
class Hideable(html.div):
def __init__(self, name, class_, *content):
super(H.Hideable, self).__init__(
H.div(H.a('show/hide %s' % (name,),
href='#',
onclick=('showhideel(getnextsibling(this));'
'return false;')),
H.div(style='display: none',
class_=class_,
*content)))
This diff is collapsed.
""" layout definition for generating api/source documents
this is the place where customization can be done
"""
import py
from py.__.doc import confrest
from py.__.apigen import linker
from py.__.doc.conftest import get_apigenpath, get_docpath
here = py.magic.autopath().dirpath()
class LayoutPage(confrest.PyPage):
""" this provides the layout and style information """
stylesheets = [(here.join('../doc/style.css'), 'style.css'),
(here.join('style.css'), 'apigen_style.css')]
scripts = [(here.join('api.js'), 'api.js')]
def __init__(self, *args, **kwargs):
self.nav = kwargs.pop('nav')
super(LayoutPage, self).__init__(*args, **kwargs)
self.relpath = self.get_relpath()
self.project.logo.attr.id = 'logo'
def get_relpath(self):
return linker.relpath(self.targetpath.strpath,
get_apigenpath().strpath) + '/'
def set_content(self, contentel):
self.contentspace.append(contentel)
def fill(self):
super(LayoutPage, self).fill()
self.body.insert(0, self.nav)
def setup_scripts_styles(self, copyto=None):
for path, name in self.stylesheets:
if copyto:
copyto.join(name).write(path.read())
self.head.append(py.xml.html.link(type='text/css',
rel='stylesheet',
href=self.relpath + name))
for path, name in self.scripts:
if copyto:
copyto.join(name).write(path.read())
self.head.append(py.xml.html.script(type="text/javascript",
src=self.relpath + name))
import py
import os
html = py.xml.html
# this here to serve two functions: first it makes the proto part of the temp