[svn r63520] * removing versioning of generated _build directory.

* removing an outdated note regarding py.std

--HG--
branch : trunk
This commit is contained in:
hpk 2009-04-02 09:37:38 +02:00
parent 4d95ec5c5c
commit ff0bdb3076
103 changed files with 2 additions and 10696 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +0,0 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 3aded863e1a877ce596c0a99a7f6ab46
tags: fbb0d17656682115ca4d033fb2f83ba1

View File

@ -1,69 +0,0 @@
======================
``py/bin/`` scripts
======================
The py-lib contains some scripts, most of which are
small ones (apart from ``py.test``) that help during
the python development process. If working
from a svn-checkout of py lib you may add ``py/bin``
to your shell ``PATH`` which should make the scripts
available on your command prompt.
``py.test``
===========
The ``py.test`` executable is the main entry point into the py-lib testing tool,
see the `py.test documentation`_.
.. _`py.test documentation`: test.html
``py.cleanup``
==============
Usage: ``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 ".".
``py.countloc``
===============
Usage: ``py.countloc [PATHS]``
Count (non-empty) lines of python code and number of python files recursively
starting from a ``PATHS`` given on the command line (starting from the current
working directory). Distinguish between test files and normal ones and report
them separately.
``py.lookup``
=============
Usage: ``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.
``py.rest``
===========
Usage: ``py.rest [PATHS] [options]``
Loot recursively for .txt files starting from ``PATHS`` and convert them to
html using docutils or to pdf files, if the ``--pdf`` option is used. For
conversion to PDF you will need several command line tools, on Ubuntu Linux
this is **texlive** and **texlive-extra-utils**.
``py.rest`` has some extra features over rst2html (which is shipped with
docutils). Most of these are still experimental, the one which is most likely
not going to change is the `graphviz`_ directive. With that you can embed .dot
files into your document and have them be converted to png (when outputting
html) and to eps (when outputting pdf). Otherwise the directive works mostly
like the image directive::
.. graphviz:: example.dot
:scale: 90
.. _`graphviz`: http://www.graphviz.org

View File

@ -1,141 +0,0 @@
=======
py.code
=======
The :api:`py.code` part of the 'py lib' contains some functionality to help
dealing with Python code objects. Even though working with Python's internal
code objects (as found on frames and callables) can be very powerful, it's
usually also quite cumbersome, because the API provided by core Python is
relatively low level and not very accessible.
The :api:`py.code` library tries to simplify accessing the code objects as well
as creating them. There is a small set of interfaces a user needs to deal with,
all nicely bundled together, and with a rich set of 'Pythonic' functionality.
source: :source:`py/code/`
Contents of the library
=======================
Every object in the :api:`py.code` library wraps a code Python object related
to code objects, source code, frames and tracebacks: the :api:`py.code.Code`
class wraps code objects, :api:`py.code.Source` source snippets,
:api:`py.code.Traceback` exception tracebacks, :api:`py.code.Frame` frame
objects (as found in e.g. tracebacks) and :api:`py.code.ExceptionInfo` the
tuple provided by sys.exc_info() (containing exception and traceback
information when an exception occurs). Also in the library is a helper function
:api:`py.code.compile()` that provides the same functionality as Python's
built-in 'compile()' function, but returns a wrapped code object.
The wrappers
============
:api:`py.code.Code`
-------------------
Code objects are instantiated with a code object or a callable as argument,
and provide functionality to compare themselves with other Code objects, get to
the source file or its contents, create new Code objects from scratch, etc.
A quick example::
>>> import py
>>> c = py.code.Code(py.path.local.read)
>>> c.path.basename
'common.py'
>>> isinstance(c.source(), py.code.Source)
True
>>> str(c.source()).split('\n')[0]
"def read(self, mode='rb'):"
source: :source:`py/code/code.py`
:api:`py.code.Source`
---------------------
Source objects wrap snippets of Python source code, providing a simple yet
powerful interface to read, deindent, slice, compare, compile and manipulate
them, things that are not so easy in core Python.
Example::
>>> s = py.code.Source("""\
... def foo():
... print "foo"
... """)
>>> str(s).startswith('def') # automatic de-indentation!
True
>>> s.isparseable()
True
>>> sub = s.getstatement(1) # get the statement starting at line 1
>>> str(sub).strip() # XXX why is the strip() required?!?
'print "foo"'
source: :source:`py/code/source.py`
:api:`py.code.Traceback`
------------------------
Tracebacks are usually not very easy to examine, you need to access certain
somewhat hidden attributes of the traceback's items (resulting in expressions
such as 'fname = tb.tb_next.tb_frame.f_code.co_filename'). The Traceback
interface (and its TracebackItem children) tries to improve this.
Example::
>>> import sys
>>> try:
... py.path.local(100) # illegal argument
... except:
... exc, e, tb = sys.exc_info()
>>> t = py.code.Traceback(tb)
>>> first = t[1] # get the second entry (first is in this doc)
>>> first.path.basename # second is in py/path/local.py
'local.py'
>>> isinstance(first.statement, py.code.Source)
True
>>> str(first.statement).strip().startswith('raise ValueError')
True
source: :source:`py/code/traceback2.py`
:api:`py.code.Frame`
--------------------
Frame wrappers are used in :api:`py.code.Traceback` items, and will usually not
directly be instantiated. They provide some nice methods to evaluate code
'inside' the frame (using the frame's local variables), get to the underlying
code (frames have a code attribute that points to a :api:`py.code.Code` object)
and examine the arguments.
Example (using the 'first' TracebackItem instance created above)::
>>> frame = first.frame
>>> isinstance(frame.code, py.code.Code)
True
>>> isinstance(frame.eval('self'), py.__.path.local.local.LocalPath)
True
>>> [namevalue[0] for namevalue in frame.getargs()]
['cls', 'path']
:api:`py.code.ExceptionInfo`
----------------------------
A wrapper around the tuple returned by sys.exc_info() (will call sys.exc_info()
itself if the tuple is not provided as an argument), provides some handy
attributes to easily access the traceback and exception string.
Example::
>>> import sys
>>> try:
... foobar()
... except:
... excinfo = py.code.ExceptionInfo()
>>> excinfo.typename
'NameError'
>>> isinstance(excinfo.traceback, py.code.Traceback)
True
>>> excinfo.exconly()
"NameError: name 'foobar' is not defined"

View File

@ -1,71 +0,0 @@
=====================================================
Coding Style for the Py lib and friendly applications
=====================================================
Honour PEP 8: Style Guide for Python Code
-----------------------------------------
First of all, if you haven't already read it, read the `PEP 8
Style Guide for Python Code`_ which, if in doubt, serves as
the default coding-style for the py lib.
Documentation and Testing
-------------------------
- generally we want to drive and interweave coding of
documentation, tests and real code as much as possible.
Without good documentation others may never know about
your latest and greatest feature.
naming
------
- directories, modules and namespaces are always **lowercase**
- classes and especially Exceptions are most often **CamelCase**
- types, i.e. very widely usable classes like the ``py.path``
family are all lower case.
- never use plural names in directory and file names
- functions/methods are lowercase and ``_`` - separated if
you really need to separate at all
- it's appreciated if you manage to name files in a directory
so that tab-completion on the shell level is as easy as possible.
committing
----------
- adding features requires adding appropriate tests.
- bug fixes should be encoded in a test before being fixed.
- write telling log messages because several people
will read your diffs, and we plan to have a search facility
over the py lib's subversion repository.
- if you add ``.txt`` or ``.py`` files to the repository then
please make sure you have ``svn:eol-style`` set to native.
which allows checkin/checkout in native line-ending format.
Miscellaneous
-------------
- Tests are the insurance that your code will be maintained
further and survives major releases.
- Try to put the tests close to the tested code, don't
overload directories with names.
- If you think of exporting new py lib APIs, discuss it first on the
`py-dev mailing list`_ and possibly write a chapter in our
`future_` book. Communication is considered a key here to make
sure that the py lib develops in a consistent way.
.. _`PEP 8 Style Guide for Python Code`: http://www.python.org/peps/pep-0008.html
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev
.. _`future`: future.html

View File

@ -1,47 +0,0 @@
Contact and communication
===================================
- **#pylib on irc.freenode.net**: you are welcome to lurk or ask questions!
- `py-dev developers list`_ development mailing list.
- `tetamap`_: Holger Krekel's blog, often about testing and py.test related news.
- `py-svn general commit mailing list`_ to follow all development commits.
- `development bug/feature tracker`_ this roundup instance serves to file bugs and track issues.
(soon to be substitued by a google-code or other hosted one).
- `merlinux.eu`_ offers teaching and consulting services.
.. _`merlinux.eu`: http://merlinux.eu
.. _future: future.html
.. _`get an account`:
.. _tetamap: http://tetamap.wordpress.com
..
get an account on codespeak
---------------------------
codespeak_ is where the subversion repository is hosted. If you know
someone who is active on codespeak already or you are otherwise known in
the community (see also: FOAF_) you will get access. But even if
you are new to the python developer community please come to the IRC
or the mailing list and ask questions, get involved.
.. _FOAF: http://en.wikipedia.org/wiki/FOAF
.. _`coding style`: coding-style.html
.. _us: http://codespeak.net/mailman/listinfo/py-dev
.. _codespeak: http://codespeak.net/
.. _`py-dev`:
.. _`development mailing list`:
.. _`py-dev developers list`: http://codespeak.net/mailman/listinfo/py-dev
.. _`subversion commit mailing list`:
.. _`py-svn`:
.. _`py-svn general commit mailing list`: http://codespeak.net/mailman/listinfo/py-svn
.. _`development bug/feature tracker`: https://codespeak.net/issue/py-dev/

View File

@ -1,28 +0,0 @@
Contents:
.. toctree::
:maxdepth: 2
:numbered:
test
execnet
path
code
bin
xml
io
log
misc
why_py
future
coding-style
download
links
contact
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,116 +0,0 @@
==============
Downloading
==============
"easy_install py"
===================================================
With a working `setuptools installation`_ you can install from the command line::
easy_install -U py
to get the latest release of the py lib. The ``-U`` switch
will trigger an upgrade if you already have an older version installed.
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.
We provide binary eggs for Windows machines.
On other systems you need a working C-compiler in order to
install the full py lib. If you don't have a compiler available
you can still install the py lib but without greenlets - look
below for the ``install_lib`` target.
**IMPORTANT NOTE**: if you are using Windows and have previous
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).
Installing on Debian or Fedora
===================================
On Debian systems look for ``python-codespeak-lib``.
*This package is probably outdated - if somebody
can help with bringing this up to date,
that would be very much appreciated.*
Dwayne Bailey has thankfully put together a Fedora `RPM`_.
.. _`RPM`: http://translate.sourceforge.net/releases/testing/fedora/pylib-0.9.2-1.fc9.noarch.rpm
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools
Downloading a tar/zip archive and installing that
===================================================
Go to the python package index (pypi) and download a tar or zip file:
http://pypi.python.org/pypi/py/
and unpack it to a directory, where you then type::
python setup.py install
If you don't have a working C-compiler you can do::
python setup.py install_lib
You will then not be able to use greenlets but otherwise
``py.test`` and all tools and APIs are fine to use.
Installing from subversion / develop mode
============================================
To follow development or help with fixing things
for the next release, checkout the complete code
and documentation source::
svn co http://codespeak.net/svn/py/release/0.9.x py-0.9.x
You can then issue::
python setup.py develop
in order to work with your checkout version.
other interesting svn checkout points::
http://codespeak.net/
svn/py/release # release tags and branches
svn/py/dist # latest stable (may or may not be a release)
svn/py/trunk # head development / merge point
Working with multiple py lib versions / svn externals
=======================================================
If you happen to have multiple versions of the py lib
around or you ship the py lib as an svn-external to
then you might want to use py lib scripts more directly.
For example if you have a project layout like this::
mypkg/
subpkg1/
tests/
tests/
py/ # as svn-external, could be specific tag/version
then you want to make sure that the actual local py lib is used
and not another system-wide version. For this you need to add
``py/bin`` or ``py\bin\win32`` respectively to your system's PATH settings.
You can do this by executing (on windows) a script to set the environment::
c:\\path\to\checkout\py\env.cmd
or on linux/osx you can add something like this to your shell
initialization::
eval `python ~/path/to/checkout/py/env.py`
to get good settings for PYTHONPATH and PATH.

View File

@ -1,235 +0,0 @@
==========
py.execnet
==========
``py.execnet`` allows to:
* instantiate local or remote Python Processes
* send code for execution in one or many processes
* asynchronously send and receive data between processes through channels
* completely avoid manual installation steps on remote places
Gateways: immediately spawn local or remote process
===================================================
In order to send code to a remote place or a subprocess
you need to instantiate a so-called Gateway object.
There are currently three Gateway classes:
* :api:`py.execnet.PopenGateway` to open a subprocess
on the local machine. Useful for making use
of multiple processors to to contain code execution
in a separated environment.
* :api:`py.execnet.SshGateway` to connect to
a remote ssh server and distribute execution to it.
* :api:`py.execnet.SocketGateway` a way to connect to
a remote Socket based server. *Note* that this method
requires a manually started
:source:py/execnet/script/socketserver.py
script. You can run this "server script" without
having the py lib installed on the remote system
and you can setup it up as permanent service.
remote_exec: execute source code remotely
===================================================
All gateways offer remote code execution via this high level function::
def remote_exec(source):
"""return channel object for communicating with the asynchronously
executing 'source' code which will have a corresponding 'channel'
object in its executing namespace."""
With `remote_exec` you send source code to the other
side and get both a local and a remote Channel_ object,
which you can use to have the local and remote site
communicate data in a structured way. Here is
an example for reading the PID::
>>> import py
>>> gw = py.execnet.PopenGateway()
>>> channel = gw.remote_exec("""
... import os
... channel.send(os.getpid())
... """)
>>> remote_pid = channel.receive()
>>> remote_pid != py.std.os.getpid()
True
.. _`Channel`:
.. _`channel-api`:
.. _`exchange data`:
Channels: bidirectionally exchange data between hosts
===================================================
A channel object allows to send and receive data between
two asynchronously running programs. When calling
`remote_exec` you will get a channel object back and
the code fragment running on the other side will
see a channel object in its global namespace.
Here is the interface of channel objects::
#
# API for sending and receiving anonymous values
#
channel.send(item):
sends the given item to the other side of the channel,
possibly blocking if the sender queue is full.
Note that items need to be marshallable (all basic
python types are).
channel.receive():
receives an item that was sent from the other side,
possibly blocking if there is none.
Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.waitclose(timeout=None):
wait until this channel is closed. Note that a closed
channel may still hold items that will be received or
send. Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.close():
close this channel on both the local and the remote side.
A remote side blocking on receive() on this channel
will get woken up and see an EOFError exception.
.. _xspec:
XSpec: string specification for gateway type and configuration
===============================================================
``py.execnet`` supports a simple extensible format for
specifying and configuring Gateways for remote execution.
You can use a string specification to instantiate a new gateway,
for example a new SshGateway::
gateway = py.execnet.makegateway("ssh=myhost")
Let's look at some examples for valid specifications.
Specification for an ssh connection to `wyvern`, running on python2.4 in the (newly created) 'mycache' subdirectory::
ssh=wyvern//python=python2.4//chdir=mycache
Specification of a python2.5 subprocess; with a low CPU priority ("nice" level). Current dir will be the current dir of the instantiator (that's true for all 'popen' specifications unless they specify 'chdir')::
popen//python=2.5//nice=20
Specification of a Python Socket server process that listens on 192.168.1.4:8888; current dir will be the 'pyexecnet-cache' sub directory which is used a default for all remote processes::
socket=192.168.1.4:8888
More generally, a specification string has this general format::
key1=value1//key2=value2//key3=value3
If you omit a value, a boolean true value is assumed. Currently
the following key/values are supported:
* ``popen`` for a PopenGateway
* ``ssh=host`` for a SshGateway
* ``socket=address:port`` for a SocketGateway
* ``python=executable`` for specifying Python executables
* ``chdir=path`` change remote working dir to given relative or absolute path
* ``nice=value`` decrease remote nice level if platforms supports it
Examples of py.execnet usage
===============================================================
Compare cwd() of Popen Gateways
----------------------------------------
A PopenGateway has the same working directory as the instantiatior::
>>> import py, os
>>> gw = py.execnet.PopenGateway()
>>> ch = gw.remote_exec("import os; channel.send(os.getcwd())")
>>> res = ch.receive()
>>> assert res == os.getcwd()
>>> gw.exit()
Synchronously receive results from two sub processes
-----------------------------------------------------
Use MultiChannels for receiving multiple results from remote code::
>>> import py
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
>>> mch = py.execnet.MultiChannel([ch1, ch2])
>>> l = mch.receive_each()
>>> assert len(l) == 2
>>> assert 1 in l
>>> assert 2 in l
Asynchronously receive results from two sub processes
-----------------------------------------------------
Use ``MultiChannel.make_receive_queue()`` for asynchronously receiving
multiple results from remote code. This standard Queue provides
``(channel, result)`` tuples which allows to determine where
a result comes from::
>>> import py
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
>>> mch = py.execnet.MultiChannel([ch1, ch2])
>>> queue = mch.make_receive_queue()
>>> chan1, res1 = queue.get() # you may also specify a timeout
>>> chan2, res2 = queue.get()
>>> res1 + res2
3
>>> assert chan1 in (ch1, ch2)
>>> assert chan2 in (ch1, ch2)
>>> assert chan1 != chan2
Receive file contents from remote SSH account
-----------------------------------------------------
Here is a small program that you can use to retrieve
contents of remote files::
import py
# open a gateway to a fresh child process
gw = py.execnet.SshGateway('codespeak.net')
channel = gw.remote_exec("""
for fn in channel:
f = open(fn, 'rb')
channel.send(f.read())
f.close()
""")
for fn in somefilelist:
channel.send(fn)
content = channel.receive()
# process content
# later you can exit / close down the gateway
gw.exit()
Instantiate a socket server in a new subprocess
-----------------------------------------------------
The following example opens a PopenGateway, i.e. a python
child process, and starts a socket server within that process
and then opens a second gateway to the freshly started
socketserver::
import py
popengw = py.execnet.PopenGateway()
socketgw = py.execnet.SocketGateway.new_remote(popengw, ("127.0.0.1", 0))
print socketgw._rinfo() # print some info about the remote environment

View File

@ -1,145 +0,0 @@
=======================================================
Visions and ideas for further development of the py lib
=======================================================
This document tries to describe directions and guiding ideas
for the near-future development of the py lib. *Note that all
statements within this document - even if they sound factual -
mostly just express thoughts and ideas. They not always refer to
real code so read with some caution.*
Distribute tests ad-hoc across multiple platforms
======================================================
After some more refactoring and unification of
the current testing and distribution support code
we'd like to be able to run tests on multiple
platforms simultanously and allow for interaction
and introspection into the (remote) failures.
Make APIGEN useful for more projects
================================================
The new APIGEN tool offers rich information
derived from running tests against an application:
argument types and callsites, i.e. it shows
the places where a particular API is used.
In its first incarnation, there are still
some specialties that likely prevent it
from documenting APIs for other projects.
We'd like to evolve to a `py.apigen` tool
that can make use of information provided
by a py.test run.
Consider APIGEN and pdb integration
===================================
The information provided by APIGEN can be used in many
different ways. An example of this could be to write
an extension to pdb which makes it available.
Imagine you could issue a pdb command
"info <function name>" and get information
regarding incoming, and outgoing types, possible
exceptions, field types and call sites.
Distribute channels/programs across networks
================================================
Apart from stabilizing setup/teardown procedures
for `py.execnet`_, we'd like to generalize its
implementation to allow connecting two programs
across multiple hosts, i.e. we'd like to arbitrarily
send "channels" across the network. Likely this
will be done by using the "pipe" model, i.e.
that each channel is actually a pair of endpoints,
both of which can be independently transported
across the network. The programs who "own"
these endpoints remain connected.
.. _`py.execnet`: execnet.html
Benchmarking and persistent storage
=========================================
For storing test results, but also benchmarking
and other information, we need a solid way
to store all kinds of information from test runs.
We'd like to generate statistics or html-overview
out of it, but also use such information to determine when
a certain test broke, or when its performance
decreased considerably.
.. _`restructured text`: http://docutils.sourceforge.net/docs/user/rst/quickref.html
.. _`python standard library`: http://www.python.org/doc/2.3.4/lib/lib.html
.. _`xpython EuroPython 2004 talk`: http://codespeak.net/svn/user/hpk/talks/xpython-talk.txt
.. _`under the xpy tree`: http://codespeak.net/svn/user/hpk/xpy/xml.py
.. _`future book`: future.html
.. _`PEP-324 subprocess module`: http://www.python.org/peps/pep-0324.html
.. _`subprocess implementation`: http://www.lysator.liu.se/~astrand/popen5/
.. _`py.test`: test.html
.. _`general-path`:
.. _`a more general view on path objects`:
Refactor path implementations to use a Filesystem Abstraction
=============================================================
It seems like a good idea to refactor all `py.path`_ Path implementations to
use an internal Filesystem abstraction. The current code base
would be transformed to have Filesystem implementations for e.g.
local, subversion and subversion "working copy" filesystems. Today
the according code is scattered through path-handling code.
On a related note, Armin Rigo has hacked `pylufs`_ and more recently has
written `pyfuse`_ which allow to
implement kernel-level linux filesystems with pure python. Now
the idea is that the mentioned filesystem implementations would
be directly usable for such linux-filesystem glue code.
In other words, implementing a `memoryfs`_ or a `dictfs`_ would
give you two things for free: a filesystem mountable at kernel level
as well as a uniform "path" object allowing you to access your
filesystem in convenient ways.
Also interesting to check out is Will McGugan's work on
his `fs package`_.
I think the main question is what the very fundamental
filesystem API should look like. Here are some doctests
on how a `draft py.fs`_ could look like. There also
is Matthew Scotts `dictproxy patch`_ which adds
``py.path.dict`` and ``py.path.proxy``.
.. _`dictproxy patch`: http://codespeak.net/pipermail/py-dev/attachments/20050128/d9595512/virtual1-0001.bin
.. _`draft py.fs`: draft_pyfs
.. _`py.path`: http://codespeak.net/py/dist/path.html
.. _`fs package`: http://www.willmcgugan.com/2008/09/21/announcing-fs-010-a-python-file-system/#comment-60276
.. _`memoryfs`: http://codespeak.net/svn/user/arigo/hack/pyfuse/memoryfs.py
.. _`dictfs`: http://codespeak.net/pipermail/py-dev/2005-January/000191.html
.. _`pylufs`: http://codespeak.net/svn/user/arigo/hack/pylufs/
.. _`pyfuse`: http://codespeak.net/svn/user/arigo/hack/pyfuse/
Integrate interactive completion
==================================
It'd be nice to integrate the bash-like
rlcompleter2_ python command line completer
into the py lib, and making it work remotely
and with pdb.
.. _rlcompleter2: http://codespeak.net/rlcompleter2/
Consider more features
==================================
There are many more features and useful classes
that might be nice to integrate. For example, we might put
Armin's `lazy list`_ implementation into the py lib.
.. _`lazy list`: http://codespeak.net/svn/user/arigo/hack/misc/collect.py

View File

@ -1,250 +0,0 @@
===============================================
Implementation and Customization of ``py.test``
===============================================
.. _`basicpicture`:
Collecting and running tests / implementation remarks
======================================================
In order to customize ``py.test`` it's good to understand
its basic architure (WARNING: these are not guaranteed
yet to stay the way they are now!)::
___________________
| |
| Collector |
|___________________|
/ \
| Item.run()
| ^
receive test Items /
| /execute test Item
| /
___________________/
| |
| Session |
|___________________|
.............................
. conftest.py configuration .
. cmdline options .
.............................
The *Session* basically receives test *Items* from a *Collector*,
and executes them via the ``Item.run()`` method. It monitors
the outcome of the test and reports about failures and successes.
.. _`collection process`:
Collectors and the test collection process
------------------------------------------
The collecting process is iterative, i.e. the session
traverses and generates a *collector tree*. Here is an example of such
a tree, generated with the command ``py.test --collectonly py/xmlobj``::
<Directory 'xmlobj'>
<Directory 'testing'>
<Module 'test_html.py' (py.__.xmlobj.testing.test_html)>
<Function 'test_html_name_stickyness'>
<Function 'test_stylenames'>
<Function 'test_class_None'>
<Function 'test_alternating_style'>
<Module 'test_xml.py' (py.__.xmlobj.testing.test_xml)>
<Function 'test_tag_with_text'>
<Function 'test_class_identity'>
<Function 'test_tag_with_text_and_attributes'>
<Function 'test_tag_with_subclassed_attr_simple'>
<Function 'test_tag_nested'>
<Function 'test_tag_xmlname'>
By default all directories not starting with a dot are traversed,
looking for ``test_*.py`` and ``*_test.py`` files. Those files
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`:
test items are collectors as well
---------------------------------
To make the reporting life simple for the session object
items offer a ``run()`` method as well. In fact the session
distinguishes "collectors" from "items" solely by interpreting
their return value. If it is a list, then we recurse into
it, otherwise we consider the "test" as passed.
.. _`package name`:
constructing the package name for test modules
-------------------------------------------------
Test modules are imported under their fully qualified
name. Given a filesystem ``fspath`` it is constructed as follows:
* walk the directories up to the last one that contains
an ``__init__.py`` file.
* perform ``sys.path.insert(0, basedir)``.
* import the root package as ``root``
* determine the fully qualified name for ``fspath`` by either:
* calling ``root.__pkg__.getimportname(fspath)`` if the
``__pkg__`` exists.` or
* otherwise use the relative path of the module path to
the base dir and turn slashes into dots and strike
the trailing ``.py``.
Customizing the testing process
===============================
writing conftest.py files
-----------------------------------
You may put conftest.py files containing project-specific
configuration in your project's root directory, it's usually
best to put it just into the same directory level as your
topmost ``__init__.py``. In fact, ``py.test`` performs
an "upwards" search starting from the directory that you specify
to be tested and will lookup configuration values right-to-left.
You may have options that reside e.g. in your home directory
but note that project specific settings will be considered
first. There is a flag that helps you debugging your
conftest.py configurations::
py.test --traceconfig
customizing the collecting and running process
-----------------------------------------------
To introduce different test items you can create
one or more ``conftest.py`` files in your project.
When the collection process traverses directories
and modules the default collectors will produce
custom Collectors and Items if they are found
in a local ``conftest.py`` file.
example: perform additional ReST checks
.......................................
With your custom collectors or items you can completely
derive from the standard way of collecting and running
tests in a localized manner. Let's look at an example.
If you invoke ``py.test --collectonly py/documentation``
then you get::
<DocDirectory 'documentation'>
<DocDirectory 'example'>
<DocDirectory 'pytest'>
<Module 'test_setup_flow_example.py' (test_setup_flow_example)>
<Class 'TestStateFullThing'>
<Instance '()'>
<Function 'test_42'>
<Function 'test_23'>
<ReSTChecker 'TODO.txt'>
<ReSTSyntaxTest 'TODO.txt'>
<LinkCheckerMaker 'checklinks'>
<ReSTChecker 'api.txt'>
<ReSTSyntaxTest 'api.txt'>
<LinkCheckerMaker 'checklinks'>
<CheckLink 'getting-started.html'>
...
In ``py/documentation/conftest.py`` you find the following
customization::
class DocDirectory(py.test.collect.Directory):
def run(self):
results = super(DocDirectory, self).run()
for x in self.fspath.listdir('*.txt', sort=True):
results.append(x.basename)
return results
def join(self, name):
if not name.endswith('.txt'):
return super(DocDirectory, self).join(name)
p = self.fspath.join(name)
if p.check(file=1):
return ReSTChecker(p, parent=self)
Directory = DocDirectory
The existence of the 'Directory' name in the
``pypy/documentation/conftest.py`` module makes the collection
process defer to our custom "DocDirectory" collector. We extend
the set of collected test items by ``ReSTChecker`` instances
which themselves create ``ReSTSyntaxTest`` and ``LinkCheckerMaker``
items. All of this instances (need to) follow the `collector API`_.
Customizing the reporting of Test Failures
--------------------------------------------
XXX implement Item.repr_run and Item.repr_path for your test items
Writing new assertion methods
-------------------------------------
XXX __tracebackhide__, and use "print"
Customizing the collection process in a module
----------------------------------------------
REPEATED WARNING: details of the collection and running process are
still subject to refactorings and thus details will change.
If you are customizing py.test at "Item" level then you
definitely want to be subscribed to the `py-dev mailing list`_
to follow ongoing development.
If you have a module where you want to take responsibility for
collecting your own test Items and possibly even for executing
a test then you can provide `generative tests`_ that yield
callables and possibly arguments as a tuple. This is especially
useful for calling application test machinery with different
parameter sets but counting each of the calls as a separate
tests.
.. _`generative tests`: test-features.html#generative-tests
The other extension possibility is about
specifying a custom test ``Item`` class which
is responsible for setting up and executing an underlying
test. Or you can extend the collection process for a whole
directory tree by putting Items in a ``conftest.py`` configuration file.
The collection process dynamically consults the *chain of conftest.py*
modules to determine collectors and items at ``Directory``, ``Module``,
``Class``, ``Function`` or ``Generator`` level respectively.
Customizing execution of Functions
----------------------------------
- ``py.test.collect.Function`` test items control execution
of a test function. ``function.run()`` will get called by the
session in order to actually run a test. The method is responsible
for performing proper setup/teardown ("Test Fixtures") for a
Function test.
- ``Function.execute(target, *args)`` methods are invoked by
the default ``Function.run()`` to actually execute a python
function with the given (usually empty set of) arguments.
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev

View File

@ -1,70 +0,0 @@
py lib: Main tools and APIs
===================================
`py.test`_ write and deploy unit- and functional tests to multiple machines.
`py.execnet`_ rapidly deploy local or remote processes from your program.
`py.path`_: use path objects to transparently access local and svn filesystems.
`py.code`_: generate python code and use advanced introspection/traceback support.
Minor support functionality
===================================
`py lib scripts`_ to make python development easier.
`py.xml`_ for generating in-memory xml/html object trees
`py.io`_: Helper Classes for Capturing of Input/Output
`py.log`_: an alpha document about the ad-hoc logging facilities
`miscellaneous features`_ describes some small but nice py lib features.
.. _`download and installation`: download.html
.. _`py-dev at codespeak net`: http://codespeak.net/mailman/listinfo/py-dev
.. _`py.execnet`: execnet.html
.. _`py.log`: log.html
.. _`py.io`: io.html
.. _`py.path`: path.html
.. _`py.code`: code.html
.. _`py.test`: test.html
.. _`py lib scripts`: bin.html
.. _`py.xml`: xml.html
.. _`Why What how py?`: why_py.html
.. _`future`: future.html
.. _`miscellaneous features`: misc.html
.. _`0.9.2 release announcement`: release-0.9.2.html
Full Contents
===================================
.. toctree::
:maxdepth: 2
:numbered:
test
execnet
path
code
bin
xml
io
log
misc
why_py
future
coding-style
links
contact
download
releases
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,43 +0,0 @@
=======
py.io
=======
The 'py' lib provides helper classes for capturing IO during
execution of a program.
IO Capturing examples
===============================================
:api:`py.io.StdCapture`
---------------------------
Basic Example:
>>> import py
>>> capture = py.io.StdCapture()
>>> print "hello"
>>> out,err = capture.reset()
>>> out.strip() == "hello"
True
For calling functions you may use a shortcut:
>>> import py
>>> def f(): print "hello"
>>> res, out, err = py.io.StdCapture.call(f)
>>> out.strip() == "hello"
True
:api:`py.io.StdCaptureFD`
---------------------------
If you also want to capture writes to the stdout/stderr
filedescriptors you may invoke:
>>> import py, sys
>>> capture = py.io.StdCaptureFD()
>>> sys.stderr.write("world")
>>> out,err = capture.reset()
>>> err
'world'

View File

@ -1,33 +0,0 @@
=====
Links
=====
Some links to ongoing discussions and comments about pylib and technics/concepts pylib uses.
* `Discussion <http://blog.ianbicking.org/site-packages-considered-harmful.html>`_
about site-packages. That's why pylib autopath and py.__.misc.dynpkg are a good idea ;-)
* `Pyinotify <http://pyinotify.sourceforge.net/>`_ uses code from pypy autopath functions.
* `Testing (WSGI) Applications with Paste <http://pythonpaste.org/testing-applications.html#the-test-environment>`_ and py.test. "This has been written with py.test in mind." Paste uses py.test.
* `Agile Testing <http://agiletesting.blogspot.com/>`_ by Grig Gheorghiu
* `Slides from 'py library overview' presentation at SoCal Piggies meeting
<http://agiletesting.blogspot.com/2005/07/slides-from-py-library-overview.html>`_
* `Python unit testing part 3: the py.test tool and library
<http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-3-pytest-tool.html>`_
* `greenlets and py.xml
<http://agiletesting.blogspot.com/2005/07/py-lib-gems-greenlets-and-pyxml.html>`_
* `Keyword-based logging with the py library
<http://agiletesting.blogspot.com/2005/06/keyword-based-logging-with-py-library.html>`_

View File

@ -1,208 +0,0 @@
.. role:: code(literal)
.. role:: file(literal)
.. XXX figure out how the code literals should be dealt with in sphinx. There is probably something builtin.
========================================
py.log documentation and musings
========================================
Foreword
========
This document is an attempt to briefly state the actual specification of the
:code:`py.log` module. It was written by Francois Pinard and also contains
some ideas for enhancing the py.log facilities.
NOTE that :code:`py.log` is subject to refactorings, it may change with
the next release.
This document is meant to trigger or facilitate discussions. It shamelessly
steals from the `Agile Testing`__ comments, and from other sources as well,
without really trying to sort them out.
__ http://agiletesting.blogspot.com/2005/06/keyword-based-logging-with-py-library.html
Logging organisation
====================
The :code:`py.log` module aims a niche comparable to the one of the
`logging module`__ found within the standard Python distributions, yet
with much simpler paradigms for configuration and usage.
__ http://www.python.org/doc/2.4.2/lib/module-logging.html
Holger Krekel, the main :code:`py` library developer, introduced
the idea of keyword-based logging and the idea of logging *producers* and
*consumers*. A log producer is an object used by the application code
to send messages to various log consumers. When you create a log
producer, you define a set of keywords that are then used to both route
the logging messages to consumers, and to prefix those messages.
In fact, each log producer has a few keywords associated with it for
identification purposes. These keywords form a tuple of strings, and
may be used to later retrieve a particular log producer.
A log producer may (or may not) be associated with a log consumer, meant
to handle log messages in particular ways. The log consumers can be
``STDOUT``, ``STDERR``, log files, syslog, the Windows Event Log, user
defined functions, etc. (Yet, logging to syslog or to the Windows Event
Log is only future plans for now). A log producer has never more than
one consumer at a given time, but it is possible to dynamically switch
a producer to use another consumer. On the other hand, a single log
consumer may be associated with many producers.
Note that creating and associating a producer and a consumer is done
automatically when not otherwise overriden, so using :code:`py` logging
is quite comfortable even in the smallest programs. More typically,
the application programmer will likely design a hierarchy of producers,
and will select keywords appropriately for marking the hierarchy tree.
If a node of the hierarchical tree of producers has to be divided in
sub-trees, all producers in the sub-trees share, as a common prefix, the
keywords of the node being divided. In other words, we go further down
in the hierarchy of producers merely by adding keywords.
Using the py.log library
================================
To use the :code:`py.log` library, the user must import it into a Python
application, create at least one log producer and one log consumer, have
producers and consumers associated, and finally call the log producers
as needed, giving them log messages.
Importing
---------
Once the :code:`py` library is installed on your system, a mere::
import py
holds enough magic for lazily importing the various facilities of the
:code:`py` library when they are first needed. This is really how
:code:`py.log` is made available to the application. For example, after
the above ``import py``, one may directly write ``py.log.Producer(...)``
and everything should work fine, the user does not have to worry about
specifically importing more modules.
Creating a producer
-------------------
There are three ways for creating a log producer instance:
+ As soon as ``py.log`` is first evaluated within an application
program, a default log producer is created, and made available under
the name ``py.log.default``. The keyword ``default`` is associated
with that producer.
+ The ``py.log.Producer()`` constructor may be explicitly called
for creating a new instance of a log producer. That constructor
accepts, as an argument, the keywords that should be associated with
that producer. Keywords may be given either as a tuple of keyword
strings, or as a single space-separated string of keywords.
+ Whenever an attribute is *taken* out of a log producer instance,
for the first time that attribute is taken, a new log producer is
created. The keywords associated with that new producer are those
of the initial producer instance, to which is appended the name of
the attribute being taken.
The last point is especially useful, as it allows using log producers
without further declarations, merely creating them *on-the-fly*.
Creating a consumer
-------------------
There are many ways for creating or denoting a log consumer:
+ A default consumer exists within the ``py.log`` facilities, which
has the effect of writing log messages on the Python standard output
stream. That consumer is associated at the very top of the producer
hierarchy, and as such, is called whenever no other consumer is
found.
+ The notation ``py.log.STDOUT`` accesses a log consumer which writes
log messages on the Python standard output stream.
+ The notation ``py.log.STDERR`` accesses a log consumer which writes
log messages on the Python standard error stream.
+ The ``py.log.File()`` constructor accepts, as argument, either a file
already opened in write mode or any similar file-like object, and
creates a log consumer able to write log messages onto that file.
+ The ``py.log.Path()`` constructor accepts a file name for its first
argument, and creates a log consumer able to write log messages into
that file. The constructor call accepts a few keyword parameters:
+ ``append``, which is ``False`` by default, may be used for
opening the file in append mode instead of write mode.
+ ``delayed_create``, which is ``False`` by default, maybe be used
for opening the file at the latest possible time. Consequently,
the file will not be created if it did not exist, and no actual
log message gets written to it.
+ ``buffering``, which is 1 by default, is used when opening the
file. Buffering can be turned off by specifying a 0 value. The
buffer size may also be selected through this argument.
+ Any user defined function may be used for a log consumer. Such a
function should accept a single argument, which is the message to
write, and do whatever is deemed appropriate by the programmer.
When the need arises, this may be an especially useful and flexible
feature.
+ The special value ``None`` means no consumer at all. This acts just
like if there was a consumer which would silently discard all log
messages sent to it.
Associating producers and consumers
-----------------------------------
Each log producer may have at most one log consumer associated with
it. A log producer gets associated with a log consumer through a
``py.log.set_consumer()`` call. That function accepts two arguments,
the first identifying a producer (a tuple of keyword strings or a single
space-separated string of keywords), the second specifying the precise
consumer to use for that producer. Until this function is called for a
producer, that producer does not have any explicit consumer associated
with it.
Now, the hierarchy of log producers establishes which consumer gets used
whenever a producer has no explicit consumer. When a log producer
has no consumer explicitly associated with it, it dynamically and
recursively inherits the consumer of its parent node, that is, that node
being a bit closer to the root of the hierarchy. In other words, the
rightmost keywords of that producer are dropped until another producer
is found which has an explicit consumer. A nice side-effect is that,
by explicitly associating a consumer with a producer, all consumer-less
producers which appear under that producer, in the hierarchy tree,
automatically *inherits* that consumer.
Writing log messages
--------------------
All log producer instances are also functions, and this is by calling
them that log messages are generated. Each call to a producer object
produces the text for one log entry, which in turn, is sent to the log
consumer for that producer.
The log entry displays, after a prefix identifying the log producer
being used, all arguments given in the call, converted to strings and
space-separated. (This is meant by design to be fairly similar to what
the ``print`` statement does in Python). The prefix itself is made up
of a colon-separated list of keywords associated with the producer, the
whole being set within square brackets.
Note that the consumer is responsible for adding the newline at the end
of the log entry. That final newline is not part of the text for the
log entry.
.. Other details
.. -------------
.. XXX: fill in details
.. + Should speak about pickle-ability of :code:`py.log`.
..
.. + What is :code:`log.get` (in :file:`logger.py`)?

View File

@ -1,216 +0,0 @@
====================================
Miscellaneous features of the py lib
====================================
Mapping the standard python library into py
===========================================
Warning: This feature is very young and thus experimental.
Be prepared to adapt your code later if you use it.
After you have worked with the py lib a bit, you might enjoy
the lazy importing, i.e. you only have to do ``import py`` and
work your way to your desired object. Using the full path
also ensures that there remains a focus on getting short paths
to objects.
The :api:`py.std` hook
----------------------
Of course, no matter what, everybody will continue to use the
python standard library because it is a very usable code base.
However, to properly support lazyness the py lib offers a way
to get to many standard modules without requiring "import"
statements. For example, to get to the print-exception
functionality of the standard library you can write::
py.std.traceback.print_exc()
without having to do anything else than the usual ``import py``
at the beginning. Note that not having imports for the
`python standard library` obviously gets rid of the *unused
import* problem. Modules only get imported when you actually
need them.
Moreover, this approach resolves some of the issues stated in
`the relative/absolute import PEP-328`_, as with the above
approach you never have ambiguity problems. The above
traceback-usage is an absolute path that will not be
accidentally get confused with local names. (Well, never put
a file ``py.py`` in an importable path, btw, mind you :-)
Automagically accessing sub packages doesn't work (yet?)
--------------------------------------------------------
If you use the :api:`py.std` hook you currently cannot magically
import nested packages which otherwise need explicit imports of
their sub-packages. For example, the suversion bindings
require you to do something like::
import svn.client
If you just do the naive thing with the py lib, i.e. write
``py.std.svn.client`` it will not work unless you previously
imported it already. The py lib currently doesn't try to
magically make this work. The :api:`py.std` hook really is
intended for Python standard modules which very seldomly (if
at all) provide such nested packages.
**Note that you may never rely** on module identity, i.e.
that ``X is py.std.X`` for any ``X``. This is to allow
us later to lazyly import nested packages. Yes, lazyness
is hard to resist :-)
Note: you get an AttributeError, not an ImportError
---------------------------------------------------
If you say ``py.std.XYZ`` and importing ``XYZ`` produces an
``ImportError`` , it will actually show up as an
``AttributeError``. It is deemed more important to adhere to
the standard ``__getattr__`` protocol than to let the
``ImportError`` pass through. For example, you might want to
do::
getattr(py.std.cStringIO, 'StringIO', py.std.StringIO.StringIO)
and you would expect that it works. It does work although it will
take away some lazyness because ``py.std.StringIO.StringIO`` will
be imported in any case.
.. _`the relative/absolute import PEP-328`: http://www.python.org/peps/pep-0328.html
Support for interaction with system utilities/binaries
======================================================
sources:
* :source:`py/process/`
* :source:`py/path/local/`
Currently, the py lib offers two ways to interact with
system executables. :api:`py.process.cmdexec()` invokes
the shell in order to execute a string. The other
one, :api:`py.path.local`'s 'sysexec()' method lets you
directly execute a binary.
Both approaches will raise an exception in case of a return-
code other than 0 and otherwise return the stdout-output
of the child process.
The shell based approach
------------------------
You can execute a command via your system shell
by doing something like::
out = py.process.cmdexec('ls -v')
However, the ``cmdexec`` approach has a few shortcomings:
- it relies on the underlying system shell
- it neccessitates shell-escaping for expressing arguments
- it does not easily allow to "fix" the binary you want to run.
- it only allows to execute executables from the local
filesystem
.. _sysexec:
local paths have ``sysexec``
----------------------------
The py lib currently offers a stripped down functionality of what
the new `PEP-324 subprocess module`_ offers. The main functionality
of synchronously executing a system executable has a straightforward API::
binsvn.sysexec('ls', 'http://codespeak.net/svn')
where ``binsvn`` is a path that points to the ``svn`` commandline
binary. Note that this function would not offer any shell-escaping
so you really have to pass in separated arguments. This idea
fits nicely into `a more general view on path objects`_.
For a first go, we are just reusing the existing `subprocess
implementation`_ but don't expose any of its API apart
from the above ``sysexec()`` method.
Note, however, that currently the support for the ``sysexec`` interface on
win32 is not thoroughly tested. If you run into problems with it, we are
interested to hear about them. If you are running a Python older than 2.4 you
will have to install the `pywin32 package`_.
.. _`future book`: future.html
.. _`PEP-324 subprocess module`: http://www.python.org/peps/pep-0324.html
.. _`subprocess implementation`: http://www.lysator.liu.se/~astrand/popen5/
.. _`a more general view on path objects`: future.html#general-path
.. _`pywin32 package`: http://pywin32.sourceforge.net/
finding an executable local path
--------------------------------
Finding an executable is quite different on multiple platforms.
Currently, the ``PATH`` environment variable based search on
unix platforms is supported::
py.path.local.sysfind('svn')
which returns the first path whose ``basename`` matches ``svn``.
In principle, `sysfind` deploys platform specific algorithms
to perform the search. On Windows, for example, it may look
at the registry (XXX).
To make the story complete, we allow to pass in a second ``checker``
argument that is called for each found executable. For example, if
you have multiple binaries available you may want to select the
right version::
def mysvn(p):
""" check that the given svn binary has version 1.1. """
line = p.execute('--version'').readlines()[0]
if line.find('version 1.1'):
return p
binsvn = py.path.local.sysfind('svn', checker=mysvn)
Cross-Python Version compatibility helpers
=============================================
sources:
* :source:`py/compat/`
* :source:`py/builtin/`
The compat and builtin namespaces help to write code using newer python features on older python interpreters.
:api:`py.compat`
----------------
:api:`py.compat` provides fixed versions (currently taken from Python 2.4.4) of
a few selected modules to be able to use them across python versions. Currently these are:
* doctest
* optparse
* subprocess
* textwrap
Note that for example ``import doctest`` and ``from py.compat import doctest`` result
into two different module objects no matter what Python version you are using.
So you should only use exactly one of these to avoid confusion in your program.
:api:`py.builtin`
-----------------
:api:`py.builtin` provides builtin functions/types that were added in later Python
versions. If the used Python version used does not provide these builtins the
py lib provides some reimplementations. These currently are:
* enumerate
* reversed
* sorted
* BaseException
* set and frozenset (using either the builtin, if available, or the sets
module)
:api:`py.builtin.BaseException` is just ``Exception`` before Python 2.5.

View File

@ -1,260 +0,0 @@
=======
py.path
=======
The 'py' lib provides a uniform high-level api to deal with filesystems
and filesystem-like interfaces: :api:`py.path`. It aims to offer a central
object to fs-like object trees (reading from and writing to files, adding
files/directories, examining the types and structure, etc.), and out-of-the-box
provides a number of implementations of this API.
Path implementations provided by :api:`py.path`
===============================================
:api:`py.path.local`
--------------------
The first and most obvious of the implementations is a wrapper around a local
filesystem. It's just a bit nicer in usage than the regular Python APIs, and
of course all the functionality is bundled together rather than spread over a
number of modules.
Example usage, here we use the :api:`py.test.ensuretemp()` function to create
a :api:`py.path.local` object for us (which wraps a directory)::
>>> import py
>>> temppath = py.test.ensuretemp('py.path_documentation')
>>> foopath = temppath.join('foo') # get child 'foo' (lazily)
>>> foopath.check() # check if child 'foo' exists
False
>>> foopath.write('bar') # write some data to it
>>> foopath.check()
True
>>> foopath.read()
'bar'
>>> foofile = foopath.open() # return a 'real' file object
>>> foofile.read(1)
'b'
:api:`py.path.svnurl` and :api:`py.path.svnwc`
----------------------------------------------
Two other :api:`py.path` implementations that the py lib provides wrap the
popular `Subversion`_ revision control system: the first (called 'svnurl')
by interfacing with a remote server, the second by wrapping a local checkout.
Both allow you to access relatively advanced features such as metadata and
versioning, and both in a way more user-friendly manner than existing other
solutions.
Some example usage of :api:`py.path.svnurl`::
.. >>> import py
.. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
>>> url = py.path.svnurl('http://codespeak.net/svn/py')
>>> info = url.info()
>>> info.kind
'dir'
>>> firstentry = url.log()[-1]
>>> import time
>>> time.strftime('%Y-%m-%d', time.gmtime(firstentry.date))
'2004-10-02'
Example usage of :api:`py.path.svnwc`::
.. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
>>> temp = py.test.ensuretemp('py.path_documentation')
>>> wc = py.path.svnwc(temp.join('svnwc'))
>>> wc.checkout('http://codespeak.net/svn/py/dist/py/path/local')
>>> wc.join('local.py').check()
True
.. _`Subversion`: http://subversion.tigris.org/
Common vs. specific API
=======================
All Path objects support a common set of operations, suitable
for many use cases and allowing to transparently switch the
path object within an application (e.g. from "local" to "svnwc").
The common set includes functions such as `path.read()` to read all data
from a file, `path.write()` to write data, `path.listdir()` to get a list
of directory entries, `path.check()` to check if a node exists
and is of a particular type, `path.join()` to get
to a (grand)child, `path.visit()` to recursively walk through a node's
children, etc. Only things that are not common on 'normal' filesystems (yet),
such as handling metadata (e.g. the Subversion "properties") require
using specific APIs.
Examples
---------------------------------
A quick 'cookbook' of small examples that will be useful 'in real life',
which also presents parts of the 'common' API, and shows some non-common
methods:
Searching `.txt` files
..........................
Search for a particular string inside all files with a .txt extension in a
specific directory.
::
>>> dirpath = temppath.ensure('testdir', dir=True)
>>> dirpath.join('textfile1.txt').write('foo bar baz')
>>> dirpath.join('textfile2.txt').write('frob bar spam eggs')
>>> subdir = dirpath.ensure('subdir', dir=True)
>>> subdir.join('textfile1.txt').write('foo baz')
>>> subdir.join('textfile2.txt').write('spam eggs spam foo bar spam')
>>> results = []
>>> for fpath in dirpath.visit('*.txt'):
... if 'bar' in fpath.read():
... results.append(fpath.basename)
>>> results.sort()
>>> results
['textfile1.txt', 'textfile2.txt', 'textfile2.txt']
Working with Paths
.......................
This example shows the :api:`py.path` features to deal with
filesystem paths Note that the filesystem is never touched,
all operations are performed on a string level (so the paths
don't have to exist, either)::
>>> p1 = py.path.local('/foo/bar')
>>> p2 = p1.join('baz/qux')
>>> p2 == py.path.local('/foo/bar/baz/qux')
True
>>> sep = py.path.local.sep
>>> p2.relto(p1).replace(sep, '/') # os-specific path sep in the string
'baz/qux'
>>> p2.bestrelpath(p1).replace(sep, '/')
'../..'
>>> p2.join(p2.bestrelpath(p1)) == p1
True
>>> p3 = p1 / 'baz/qux' # the / operator allows joining, too
>>> p2 == p3
True
>>> p4 = p1 + ".py"
>>> p4.basename == "bar.py"
True
>>> p4.ext == ".py"
True
>>> p4.purebasename == "bar"
True
This should be possible on every implementation of :api:`py.path`, so
regardless of whether the implementation wraps a UNIX filesystem, a Windows
one, or a database or object tree, these functions should be available (each
with their own notion of path seperators and dealing with conversions, etc.).
Checking path types
.......................
Now we will show a bit about the powerful 'check()' method on paths, which
allows you to check whether a file exists, what type it is, etc.::
>>> file1 = temppath.join('file1')
>>> file1.check() # does it exist?
False
>>> file1 = file1.ensure(file=True) # 'touch' the file
>>> file1.check()
True
>>> file1.check(dir=True) # is it a dir?
False
>>> file1.check(file=True) # or a file?
True
>>> file1.check(ext='.txt') # check the extension
False
>>> textfile = temppath.ensure('text.txt', file=True)
>>> textfile.check(ext='.txt')
True
>>> file1.check(basename='file1') # we can use all the path's properties here
True
Setting svn-properties
.......................
As an example of 'uncommon' methods, we'll show how to read and write
properties in an :api:`py.path.svnwc` instance::
.. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
>>> wc.propget('foo')
''
>>> wc.propset('foo', 'bar')
>>> wc.propget('foo')
'bar'
>>> len(wc.status().prop_modified) # our own props
1
>>> msg = wc.revert() # roll back our changes
>>> len(wc.status().prop_modified)
0
SVN authentication
.......................
Some uncommon functionality can also be provided as extensions, such as SVN
authentication::
.. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
>>> auth = py.path.SvnAuth('anonymous', 'user', cache_auth=False,
... interactive=False)
>>> wc.auth = auth
>>> wc.update() # this should work
>>> path = wc.ensure('thisshouldnotexist.txt')
>>> try:
... path.commit('testing')
... except py.process.cmdexec.Error, e:
... pass
>>> 'authorization failed' in str(e)
True
Known problems / limitations
===================================
* The SVN path objects require the "svn" command line,
there is currently no support for python bindings.
Parsing the svn output can lead to problems, particularly
regarding if you have a non-english "locales" setting.
* While the path objects basically work on windows,
there is no attention yet on making unicode paths
work or deal with the famous "8.3" filename issues.
Future plans
============
The Subversion path implementations are based
on the `svn` command line, not on the bindings.
It makes sense now to directly use the bindings.
Moreover, it would be good, also considering
`py.execnet`_ distribution of programs, to
be able to manipulate Windows Paths on Linux
and vice versa. So we'd like to consider
refactoring the path implementations
to provide this choice (and getting rid
of platform-dependencies as much as possible).
There is some experimental small approach
(:source:`py/path/gateway/`) aiming at having
a convenient Remote Path implementation
and some considerations about future
works in the according :source:`py/path/gateway/TODO.txt`
There are various hacks out there to have
Memory-Filesystems and even path objects
being directly mountable under Linux (via `fuse`).
However, the Path object implementations
do not internally have a clean abstraction
of going to the filesystem - so with some
refactoring it should become easier to
have very custom Path objects, still offering
the quite full interface without requiring
to know about all details of the full path
implementation.
.. _`py.execnet`: execnet.html

View File

@ -1,7 +0,0 @@
py lib 1.0.0: XXX
======================================================================
Welcome to the 1.0.0 py lib release - a library aiming to
support agile and test-driven python development on various levels.
XXX

View File

@ -1,27 +0,0 @@
py lib 0.9.2: bugfix release
=============================
Welcome to the 0.9.2 py lib and py.test release -
mainly fixing Windows issues, providing better
packaging and integration with setuptools.
Here is a quick summary of what the py lib provides:
* 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")
* py.path: path abstractions over local and subversion files
* rich documentation of py's exported API
* tested against Linux, Win32, OSX, works on python 2.3-2.6
See here for more information:
Pypi pages: http://pypi.python.org/pypi/py/
Download/Install: http://codespeak.net/py/0.9.2/download.html
Documentation/API: http://codespeak.net/py/0.9.2/index.html
best and have fun,
holger krekel

View File

@ -1,31 +0,0 @@
py lib 0.9.0: py.test, distributed execution, greenlets and more
======================================================================
Welcome to the 0.9.0 py lib release - a library aiming to
support agile and test-driven python development on various levels.
Main API/Tool 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.magic.greenlet: micro-threads on standard CPython ("stackless-light")
* py.path: path abstractions over local and subversion files
* rich documentation of py's exported API
* tested against Linux, OSX and partly against Win32, python 2.3-2.5
All these features and their API have extensive documentation,
generated with the new "apigen", which we intend to make accessible
for other python projects as well.
Download/Install: http://codespeak.net/py/0.9.0/download.html
Documentation/API: http://codespeak.net/py/0.9.0/index.html
Work on the py lib has been partially funded by the
European Union IST programme and by http://merlinux.de
within the PyPy project.
best, have fun and let us know what you think!
holger krekel, Maciej Fijalkowski,
Guido Wesdorp, Carl Friedrich Bolz

View File

@ -1,12 +0,0 @@
=============
Release notes
=============
Contents:
.. toctree::
:maxdepth: 1
release-1.0.0
release-0.9.2
release-0.9.0

View File

@ -1,23 +0,0 @@
Test configuration
========================
test options and values
-----------------------------
You can see all available command line options by running::
py.test -h
py.test will lookup values of options in this order:
* option value supplied at command line
* content of environment variable ``PYTEST_OPTION_NAME=...``
* ``name = ...`` setting in the nearest ``conftest.py`` file.
The name of an option usually is the one you find
in the longform of the option, i.e. the name
behind the ``--`` double-dash.
IOW, you can set default values for options per project, per
home-directoray, per shell session or per test-run.

View File

@ -1,125 +0,0 @@
.. _`distribute tests across machines`:
===================
Distributed testing
===================
``py.test`` can ad-hoc distribute test runs to multiple CPUs or remote
machines. This allows to speed up development or to use special resources
of remote machines. Before running tests remotely, ``py.test`` efficiently
synchronizes your program source code to the remote place. All test results
are reported back and displayed to your local test session. You may
specify different Python versions and interpreters.
Synchronisation and running of tests only requires
a bare Python installation on the remote side. No
special software is installed - this is realized
by use of the **zero installation** `py.execnet`_ mechanisms.
Speed up test runs by sending tests to multiple CPUs
----------------------------------------------------------
To send tests to multiple CPUs, type::
py.test -n NUM
Especially for longer running tests or tests requiring
a lot of IO this can lead to considerable speed ups.
Running tests in a Python subprocess
----------------------------------------
To instantiate a python2.4 sub process and send tests to it, you may type::
py.test -d --tx popen//python=python2.4
This will start a subprocess which is run with the "python2.4"
Python interpreter, found in your system binary lookup path.
If you prefix the --tx option value like this::
--tx 3*popen//python=python2.4
then three subprocesses would be created and tests
will be load-balanced across these three processes.
Sending tests to remote SSH accounts
-----------------------------------------------
Suppose you have a package ``mypkg`` which contains some
tests that you can successfully run locally. And you
have a ssh-reachable machine ``myhost``. Then
you can ad-hoc distribute your tests by typing::
py.test -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg
This will synchronize your ``mypkg`` package directory
to an remote ssh account and then locally collect tests
and send them to remote places for execution.
You can specify multiple ``--rsyncdir`` directories
to be sent to the remote side.
Sending tests to remote Socket Servers
----------------------------------------
Download the single-module `socketserver.py`_ Python program
and run it like this::
python socketserver.py
It will tell you that it starts listening on the default
port. You can now on your home machine specify this
new socket host with something like this::
py.test -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
.. _`atonce`:
Running tests on many platforms at once
-------------------------------------------------------------
The basic command to run tests on multiple platforms is::
py.test --dist=each --tx=spec1 --tx=spec2
If you specify a windows host, an OSX host and a Linux
environment this command will send each tests to all
platforms - and report back failures from all platforms
at once. The provided specifications strings
use the `xspec syntax`_.
.. _`xspec syntax`: execnet.html#xspec
.. _`socketserver.py`: http://codespeak.net/svn/py/dist/py/execnet/script/socketserver.py
.. _`py.execnet`: execnet.html
Specifying test exec environments in a conftest.py
-------------------------------------------------------------
Instead of specifying command line options, you can
put options values in a ``conftest.py`` file like this::
pytest_option_tx = ['ssh=myhost//python=python2.5', 'popen//python=python2.5']
pytest_option_dist = True
Any commandline ``--tx`` specifictions will add to the list of available execution
environments.
Specifying "rsync" dirs in a conftest.py
-------------------------------------------------------------
In your ``mypkg/conftest.py`` you may specify directories to synchronise
or to exclude::
rsyncdirs = ['.', '../plugins']
rsyncignore = ['_cache']
These directory specifications are relative to the directory
where the ``conftest.py`` is found.

View File

@ -1,54 +0,0 @@
Working Examples
================
managing state at module, class and method level
------------------------------------------------------------
Here is a working example for what goes on when you setup modules,
classes and methods::
# [[from py/documentation/example/pytest/test_setup_flow_example.py]]
def setup_module(module):
module.TestStateFullThing.classcount = 0
class TestStateFullThing:
def setup_class(cls):
cls.classcount += 1
def teardown_class(cls):
cls.classcount -= 1
def setup_method(self, method):
self.id = eval(method.func_name[5:])
def test_42(self):
assert self.classcount == 1
assert self.id == 42
def test_23(self):
assert self.classcount == 1
assert self.id == 23
def teardown_module(module):
assert module.TestStateFullThing.classcount == 0
For this example the control flow happens as follows::
import test_setup_flow_example
setup_module(test_setup_flow_example)
setup_class(TestStateFullThing)
instance = TestStateFullThing()
setup_method(instance, instance.test_42)
instance.test_42()
setup_method(instance, instance.test_23)
instance.test_23()
teardown_class(TestStateFullThing)
teardown_module(test_setup_flow_example)
Note that ``setup_class(TestStateFullThing)`` is called and not
``TestStateFullThing.setup_class()`` which would require you
to insert ``setup_class = classmethod(setup_class)`` to make
your setup function callable. Did we mention that lazyness
is a virtue?

View File

@ -1,64 +0,0 @@
===============
Writing plugins
===============
Learning by examples
=====================
XXX
adding custom options
----------------------
py.test supports adding of standard optparse_ Options.
A plugin may implement the ``addoption`` hook for registering
custom options::
class ConftestPlugin:
def pytest_addoption(self, parser):
parser.addoption("-M", "--myopt", action="store",
help="specify string to set myopt")
def pytest_configure(self, config):
if config.option.myopt:
# do action based on option value
.. _optparse: http://docs.python.org/library/optparse.html
Setting default values for test options
=======================================
You can see all available command line options by running::
py.test -h
py.test will lookup values of options in this order:
* option value supplied at command line
* content of environment variable ``PYTEST_OPTION_NAME=...``
* ``name = ...`` setting in the nearest ``conftest.py`` file.
The name of an option usually is the one you find
in the longform of the option, i.e. the name
behind the ``--`` double-dash.
IOW, you can set default values for options per project, per
home-directoray, per shell session or per test-run.
Plugin methods
=======================================
A Plugin class may implement the following attributes and methods:
XXX
_`pytest event`:
Pytest Events
=======================================
XXX

View File

@ -1,279 +0,0 @@
==================================================
Features
==================================================
py.test is a standalone-tool that collects and runs tests for
your Python application and modules. py.test works across
linux, windows and osx and on Python 2.3 - Python 2.6.
It aims to support *unit-tests* and *functional tests* written
in Python and is used in projects that run more than 10000
tests regularly.
py.test presents a clean and powerful command line interface
and strives to generally make testing a fun effort.
automatically collects and executes tests
===============================================
py.test discovers tests automatically by inspect specified
directories or files. By default, it collects all python
modules a leading ``test_`` or trailing ``_test`` filename.
From each test module every function with a leading ``test_``
or class with a leading ``Test`` name is collected.
.. _`generative tests`:
.. _`collection process`: impl-test.html#collection-process
load-balance tests to multiple CPUs
===================================
For large test suites you can distribute your
tests to multiple CPUs by issuing for example::
py.test -n 3
Read more on `distributed testing`_.
.. _`distributed testing`: test-dist.html
Distribute tests across machines
===================================
py.test supports the sending of tests to
remote ssh-accounts or socket servers.
It can `ad-hoc run your test on multiple
platforms one a single test run`. Ad-hoc
means that there are **no installation
requirements whatsoever** on the remote side.
.. _`ad-hoc run your test on multiple platforms one a single test run`: test-dist.html#atonce
extensive debugging support
===================================
testing starts immediately
--------------------------
Testing starts as soon as the first ``test item``
is collected. The collection process is iterative
and does not need to complete before your first
test items are executed.
support for modules containing tests
--------------------------------------
As ``py.test`` operates as a separate cmdline
tool you can easily have a command line utility and
some tests in the same file.
debug with the ``print`` statement
----------------------------------
By default, ``py.test`` catches text written to stdout/stderr during
the execution of each individual test. This output will only be
displayed however if the test fails; you will not see it
otherwise. This allows you to put debugging print statements in your
code without being overwhelmed by all the output that might be
generated by tests that do not fail.
Each failing test that produced output during the running of the test
will have its output displayed in the ``recorded stdout`` section.
The catching of stdout/stderr output can be disabled using the
``--nocapture`` option to the ``py.test`` tool. Any output will
in this case be displayed as soon as it is generated.
test execution order
--------------------------------
Tests usually run in the order in which they appear in the files.
However, tests should not rely on running one after another, as
this prevents more advanced usages: running tests
distributedly or selectively, or in "looponfailing" mode,
will cause them to run in random order.
assert with the ``assert`` statement
----------------------------------------
``py.test`` allows to use the standard python
``assert statement`` for verifying expectations
and values in Python tests. For example, you can
write the following in your tests::
assert hasattr(x, 'attribute')
to state that your object has a certain ``attribute``. In case this
assertion fails you will see the value of ``x``. Intermediate
values are computed by executing the assert expression a second time.
If you execute code with side effects, e.g. read from a file like this::
assert f.read() != '...'
then you may get a warning from pytest if that assertions
first failed and then succeeded.
asserting expected exceptions
----------------------------------------
In order to write assertions about exceptions, you use
one of two forms::
py.test.raises(Exception, func, *args, **kwargs)
py.test.raises(Exception, "func(*args, **kwargs)")
both of which execute the given function with args and kwargs and
asserts that the given ``Exception`` is raised. The reporter will
provide you with helpful output in case of failures such as *no
exception* or *wrong exception*.
useful tracebacks, recursion detection
--------------------------------------
A lot of care is taken to present nice tracebacks in case of test
failure. Try::
py.test py/doc/example/pytest/failure_demo.py
to see a variety of tracebacks, each representing a different
failure situation.
``py.test`` uses the same order for presenting tracebacks as Python
itself: the oldest function call is shown first, and the most recent call is
shown last. A ``py.test`` reported traceback starts with your
failing test function. If the maximum recursion depth has been
exceeded during the running of a test, for instance because of
infinite recursion, ``py.test`` will indicate where in the
code the recursion was taking place. You can inhibit
traceback "cutting" magic by supplying ``--fulltrace``.
There is also the possibility of using ``--tb=short`` to get regular CPython
tracebacks. Or you can use ``--tb=no`` to not show any tracebacks at all.
no inheritance requirement
--------------------------
Test classes are recognized by their leading ``Test`` name. Unlike
``unitest.py``, you don't need to inherit from some base class to make
them be found by the test runner. Besides being easier, it also allows
you to write test classes that subclass from application level
classes.
testing for deprecated APIs
------------------------------
In your tests you can use ``py.test.deprecated_call(func, *args, **kwargs)``
to test that a particular function call triggers a DeprecationWarning.
This is useful for testing phasing out of old APIs in your projects.
advanced test selection / skipping
=========================================================
dynamically skipping tests
-------------------------------
If you want to skip tests you can use ``py.test.skip`` within
test or setup functions. Example::
py.test.skip("message")
You can also use a helper to skip on a failing import::
docutils = py.test.importorskip("docutils")
or to skip if a library does not have the right version::
docutils = py.test.importorskip("docutils", minversion="0.3")
The version will be read from the module's ``__version__`` attribute.
.. _`selection by keyword`:
selecting/unselecting tests by keyword
---------------------------------------------
Pytest's keyword mechanism provides a powerful way to
group and selectively run tests in your test code base.
You can selectively run tests by specifiying a keyword
on the command line. Examples::
py.test -k test_simple
py.test -k "-test_simple"
will run all tests matching (or not matching) the
"test_simple" keyword. Note that you need to quote
the keyword if "-" is recognized as an indicator
for a commandline option. Lastly, you may use::
py.test. -k "test_simple:"
which will run all tests after the expression has *matched once*, i.e.
all tests that are seen after a test that matches the "test_simple"
keyword.
By default, all filename parts and
class/function names of a test function are put into the set
of keywords for a given test. You may specify additional
kewords like this::
@py.test.mark(webtest=True)
def test_send_http():
...
disabling a test class
----------------------
If you want to disable a complete test class you
can set the class-level attribute ``disabled``.
For example, in order to avoid running some tests on Win32::
class TestPosixOnly:
disabled = sys.platform == 'win32'
def test_xxx(self):
...
generative tests: yielding parametrized tests
====================================================
*Generative tests* are test methods that are *generator functions* which
``yield`` callables and their arguments. This is most useful for running a
test function multiple times against different parameters. Example::
def test_generative():
for x in (42,17,49):
yield check, x
def check(arg):
assert arg % 7 == 0 # second generated tests fails!
Note that ``test_generative()`` will cause three tests
to get run, notably ``check(42)``, ``check(17)`` and ``check(49)``
of which the middle one will obviously fail.
To make it easier to distinguish the generated tests it is possible to specify an explicit name for them, like for example::
def test_generative():
for x in (42,17,49):
yield "case %d" % x, check, x
extensible plugin system
=========================================
py.test itself consists of many plugins
and you can easily write new `py.test plugins`_
for these purposes:
* reporting extensions
* customizing collection and run of tests
* running non-python tests
* managing test state setup
.. _`py.test plugins`: test-plugins.html
.. _`reStructured Text`: http://docutils.sourceforge.net
.. _`Python debugger`: http://docs.python.org/lib/module-pdb.html
.. _nose: http://somethingaboutorange.com/mrl/projects/nose/

View File

@ -1,71 +0,0 @@
================
Included plugins
================
Many of py.test's features are implemented as a plugin.
Included plugins
================
You can find the source code of all default plugins in
http://codespeak.net/svn/py/trunk/py/test/plugin/
plugins that add reporting asepcts
-----------------------------------
pytest_terminal: default reporter for writing info to terminals
pytest_resultlog: log test results in machine-readable form to a file
pytest_eventlog: log all internal pytest events to a file
plugins for adding new test types
-----------------------------------
pytest_unittest: run traditional unittest TestCase instances
pytest_doctest: run doctests in python modules or .txt files
pytest_restdoc: provide RestructuredText syntax and link checking
plugins for python test functions
-----------------------------------
pytest_xfail: provides "expected to fail" test marker
pytest_tmpdir: provide temporary directories to test functions
pytest_plugintester: generic plugin apichecks, support for functional plugin tests
pytest_apigen: tracing values of function/method calls when running tests
Loading plugins and specifying dependencies
============================================
py.test loads and configures plugins at tool startup:
* by reading the ``PYTEST_PLUGINS`` environment variable
and importing the comma-separated list of plugin names.
* by loading all plugins specified via one or more ``-p name``
command line options.
* by loading all plugins specified via a ``pytest_plugins``
variable in ``conftest.py`` files or test modules.
example: ensure a plugin is loaded
-----------------------------------
If you create a ``conftest.py`` file with the following content::
pytest_plugins = "pytest_myextension",
then all tests in that directory and below it will run with
an instantiated "pytest_myextension". Here is how instantiation
takes place:
* the module ``pytest_extension`` will be imported and
and its contained `ExtensionPlugin`` class will
be instantiated. A plugin module may specify its
dependencies via another ``pytest_plugins`` definition.

View File

@ -1,59 +0,0 @@
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools
==================
Quickstart
==================
This document assumes basic python knowledge. If you have a
`setuptools installation`_, install ``py.test`` by typing::
easy_install -U py
For alternative installation methods please see the download_ page.
You should now have a ``py.test`` command line tool and can
look at its documented cmdline options via this command::
py.test -h
Writing and running a test
==========================
``py.test`` is the command line tool to run tests.
Let's write a first test module by putting the following
test function into a ``test_sample.py`` file::
# content of test_sample.py
def test_answer():
assert 42 == 43
Now you can run the test by passing it as an argument::
py.test test_sample.py
What does happen here? ``py.test`` looks for functions and
methods in the module that start with ``test_``. It then
executes those tests. Assertions about test outcomes are
done via the standard ``assert`` statement.
You can also use ``py.test`` to run all tests in a directory structure by
invoking it without any arguments::
py.test
This will automatically collect and run any Python module whose filenames
start with ``test_`` or ends with ``_test`` from the directory and any
subdirectories, starting with the current directory, and run them. Each
Python test module is inspected for test methods starting with ``test_``.
.. Organising your tests
.. ---------------------------
Please refer to `features`_ for a walk through the basic features.
.. _download: download.html
.. _features: test-features.html

View File

@ -1,42 +0,0 @@
=======
py.test
=======
*py.test* is a tool for:
* rapidly writing unit- and functional tests in Python
* writing tests for non-python code and data
* receiving useful reports on test failures
* distributing tests to multiple CPUs and remote environments
quickstart_: for getting started immediately.
features_: a walk through basic features and usage.
plugins_: using available plugins.
extend_: writing plugins and advanced configuration.
`distributed testing`_ how to distribute test runs to other machines and platforms.
.. _quickstart: test-quickstart.html
.. _features: test-features.html
.. _plugins: test-plugins.html
.. _extend: test-ext.html
.. _`distributed testing`: test-dist.html
Contents:
.. toctree::
:maxdepth: 2
test-quickstart
test-features
test-plugins
test-ext
test-dist
test-config
test-examples
impl-test

View File

@ -1,182 +0,0 @@
==============================================
Why, who, what and how do you do *the py lib*?
==============================================
Why did we start the py lib?
============================
Among the main motivation for the py lib and its flagship
py.test tool were:
- to test applications with a testing tool that provides
advanced features out of the box, yet allows full customization
per-project.
- distribute applications in an ad-hoc way both for testing
and for application integration purposes.
- help with neutralizing platform and python version differences
- offer a uniform way to access local and remote file resources
- offer some unique features like micro-threads (greenlets)
What is the py libs current focus?
==================================
testing testing testing
-----------------------
Currently, the main focus of the py lib is to get a decent
`test environment`_, indeed to produce the best one out there.
Writing, distributing and deploying tests should become
a snap ... and fun!
On a side note: automated tests fit very well to the dynamism
of Python. Automated tests ease development and allow fast
refactoring cycles. Automated tests are a means of
communication as well.
ad-hoc distribution of programs
------------------------------------
The py lib through its `py.execnet`_ namespaces offers
support for ad-hoc distributing programs across
a network and subprocesses. We'd like to generalize
this approach further to instantiate and let whole
ad-hoc networks communicate with each other while
keeping to a simple programming model.
.. _`py.execnet`: execnet.html
allowing maximum refactoring in the future ...
----------------------------------------------
explicit name export control
............................
In order to allow a fast development pace across versions of
the py lib there is **explicit name export control**. You
should only see names which make sense to use from the outside
and which the py lib developers want to guarantee across versions.
However, you don't need to treat the ``py`` lib as
anything special. You can simply use the usual ``import``
statement and will not notice much of a difference - except that
the namespaces you'll see from the ``py`` lib are relatively
clean and have no clutter.
Release policy & API maintenance
........................................
We'll talk about major, minor and micro numbers as the three
numbers in "1.2.3" respectively. These are the
the rough release policies:
- Micro-releases are bug fix releases and should not introduce
new names to the public API. They may add tests and thus
further define the behaviour of the py lib. They may
completly change the implementation but the public API
tests should continue to run (unless they needed to
get fixed themselves).
- No **tested feature** of the exported py API shall vanish
across minor releases until it is marked deprecated.
For example, pure API tests of a future version 1.0 are to
continue to fully run on 1.1 and so on. If an API gets
deprecated with a minor release it goes with the next minor
release. Thus if you don't use deprecated APIs you should
be able to use the next two minor releases. However, if
you relied on some untested implementation behaviour,
you may still get screwed. Solution: add API tests to the
py lib :-) It's really the tests that make the difference.
- Pure API tests are not allowed to access any implementation
level details. For example, accessing names starting with
a single leading '_' is generally seen as an implementation
level detail.
- major releases *should*, but are not required to, pass
all API tests of the previous latest major released
version.
the need to find the right *paths* ...
--------------------------------------
Another focus are well tested so called *path* implementations
that allow you to seemlessly work with different backends,
currently a local filesystem, subversion working copies and
subversion remote URLs.
How does py development work?
=============================
Communication and coding style
------------------------------
We are discussing things on our `py-dev mailing list`_
and collaborate via the codespeak subversion repository.
We follow a `coding style`_ which strongly builds on `PEP 8`_,
the basic python coding style document.
It's easy to get commit rights especially if you are an
experienced python developer and share some of the
frustrations described above.
Licensing
-----------------
The Py lib is released under the MIT license and all
contributors need to release their contributions
under this license as well.
connections with PyPy_
---------------------------------
A major motivation for writing the py lib stems from needs
during PyPy_ development, most importantly testing and
file system access issues. PyPy puts a lot of pressure
on a testing environment and thus is a good **reality test**.
Who is "we"?
=============================
Some initial code was written from *Jens-Uwe Mager* and *Holger
Krekel*, after which Holger continued on a previous
incarnations of the py.test tool (known first as 'utest', then
as 'std.utest', now for some 2 years 'py.test').
Helpful discussions took place with *Martijn Faassen*, *Stephan
Schwarzer*, *Brian Dorsey*, *Grigh Gheorghiu* and then
*Armin Rigo* who contributed important parts.
He and Holger came up with a couple of iterations of the
testing-code that reduced the API to basically nothing: just the
plain assert statement and a ``py.test.raises`` method to
check for occuring exceptions within tests.
Currently (as of 2007), there are more people involved
and also have worked funded through merlinux_ and the
PyPy EU project, Carl Friedrich Bolz, Guido Wesdorp
and Maciej Fijalkowski who contributed particularly
in 2006 and 2007 major parts of the py lib.
.. _`talk at EP2004`: http://codespeak.net/svn/user/hpk/talks/std-talk.txt
.. _`coding style`: coding-style.html
.. _`PEP 8`: http://www.python.org/peps/pep-0008.html
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev
.. _`test environment`: test.html
.. _`PyPy`: http://codespeak.net/pypy
.. _future: future.html
.. _`py.test tool and library`: test.html
.. _merlinux: http://merlinux.de
--
.. [#] FOSS is an evolving acronym for Free and Open Source Software

View File

@ -1,169 +0,0 @@
====================================================
py.xml: Lightweight and flexible xml/html generation
====================================================
Motivation
==========
There are a plethora of frameworks and libraries to generate
xml and html trees. However, many of them are large, have a
steep learning curve and are often hard to debug. Not to
speak of the fact that they are frameworks to begin with.
The py lib strives to offer enough functionality to represent
itself and especially its API in html or xml.
.. _xist: http://www.livinglogic.de/Python/xist/index.html
.. _`exchange data`: execnet.html#exchange-data
a pythonic object model , please
================================
The py lib offers a pythonic way to generate xml/html, based on
ideas from xist_ which `uses python class objects`_ to build
xml trees. However, xist_'s implementation is somewhat heavy
because it has additional goals like transformations and
supporting many namespaces. But its basic idea is very easy.
.. _`uses python class objects`: http://www.livinglogic.de/Python/xist/Howto.html
generating arbitrary xml structures
-----------------------------------
With ``py.xml.Namespace`` you have the basis
to generate custom xml-fragments on the fly::
class ns(py.xml.Namespace):
"my custom xml namespace"
doc = ns.books(
ns.book(
ns.author("May Day"),
ns.title("python for java programmers"),),
ns.book(
ns.author("why"),
ns.title("Java for Python programmers"),),
publisher="N.N",
)
print doc.unicode(indent=2).encode('utf8')
will give you this representation::
<books publisher="N.N">
<book>
<author>May Day</author>
<title>python for java programmers</title></book>
<book>
<author>why</author>
<title>Java for Python programmers</title></book></books>
In a sentence: positional arguments are child-tags and
keyword-arguments are attributes.
On a side note, you'll see that the unicode-serializer
supports a nice indentation style which keeps your generated
html readable, basically through emulating python's white
space significance by putting closing-tags rightmost and
almost invisible at first glance :-)
basic example for generating html
---------------------------------
Consider this example::
from py.xml import html # html namespace
paras = "First Para", "Second para"
doc = html.html(
html.head(
html.meta(name="Content-Type", value="text/html; charset=latin1")),
html.body(
[html.p(p) for p in paras]))
print unicode(doc).encode('latin1')
Again, tags are objects which contain tags and have attributes.
More exactly, Tags inherit from the list type and thus can be
manipulated as list objects. They additionally support a default
way to represent themselves as a serialized unicode object.
If you happen to look at the py.xml implementation you'll
note that the tag/namespace implementation consumes some 50 lines
with another 50 lines for the unicode serialization code.
CSS-styling your html Tags
--------------------------
One aspect where many of the huge python xml/html generation
frameworks utterly fail is a clean and convenient integration
of CSS styling. Often, developers are left alone with keeping
CSS style definitions in sync with some style files
represented as strings (often in a separate .css file). Not
only is this hard to debug but the missing abstractions make
it hard to modify the styling of your tags or to choose custom
style representations (inline, html.head or external). Add the
Browers usual tolerance of messyness and errors in Style
references and welcome to hell, known as the domain of
developing web applications :-)
By contrast, consider this CSS styling example::
class my(html):
"my initial custom style"
class body(html.body):
style = html.Style(font_size = "120%")
class h2(html.h2):
style = html.Style(background = "grey")
class p(html.p):
style = html.Style(font_weight="bold")
doc = my.html(
my.head(),
my.body(
my.h2("hello world"),
my.p("bold as bold can")
)
)
print doc.unicode(indent=2)
This will give you a small'n mean self contained
represenation by default::
<html>
<head/>
<body style="font-size: 120%">
<h2 style="background: grey">hello world</h2>
<p style="font-weight: bold">bold as bold can</p></body></html>
Most importantly, note that the inline-styling is just an
implementation detail of the unicode serialization code.
You can easily modify the serialization to put your styling into the
``html.head`` or in a separate file and autogenerate CSS-class
names or ids.
Hey, you could even write tests that you are using correct
styles suitable for specific browser requirements. Did i mention
that the ability to easily write tests for your generated
html and its serialization could help to develop _stable_ user
interfaces?
More to come ...
----------------
For now, i don't think we should strive to offer much more
than the above. However, it is probably not hard to offer
*partial serialization* to allow generating maybe hundreds of
complex html documents per second. Basically we would allow
putting callables both as Tag content and as values of
attributes. A slightly more advanced Serialization would then
produce a list of unicode objects intermingled with callables.
At HTTP-Request time the callables would get called to
complete the probably request-specific serialization of
your Tags. Hum, it's probably harder to explain this than to
actually code it :-)
.. _`py.test`: test.html

View File

@ -1,414 +0,0 @@
/**
* Sphinx stylesheet -- basic theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* -- main layout ----------------------------------------------------------- */
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 0;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
/* -- other body styles ----------------------------------------------------- */
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlight {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View File

@ -1,201 +0,0 @@
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: sans-serif;
font-size: 100%;
background-color: #11303d;
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: #1c4e63;
}
div.body {
background-color: #ffffff;
color: #000000;
padding: 0 20px 30px 20px;
}
div.footer {
color: #ffffff;
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #ffffff;
text-decoration: underline;
}
div.related {
background-color: #133f52;
line-height: 30px;
color: #ffffff;
}
div.related a {
color: #ffffff;
}
div.sphinxsidebar {
}
div.sphinxsidebar h3 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: #ffffff;
}
div.sphinxsidebar h4 {
font-family: 'Trebuchet MS', sans-serif;
color: #ffffff;
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: #ffffff;
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: #ffffff;
}
div.sphinxsidebar a {
color: #98dbcc;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #355f7c;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Trebuchet MS', sans-serif;
background-color: #f2f2f2;
font-weight: normal;
color: #20435c;
border-bottom: 1px solid #ccc;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 5px;
background-color: #eeffcc;
color: #333333;
line-height: 120%;
border: 1px solid #ac9;
border-left: none;
border-right: none;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 0.95em;
}

View File

@ -1,232 +0,0 @@
/// XXX: make it cross browser
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
*/
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
"group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {}
}
/**
* small helper function to urldecode strings
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
}
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
}
/**
* small function to check if an array contains
* a given item.
*/
jQuery.contains = function(arr, item) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == item)
return true;
}
return false;
}
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) {
var span = document.createElement("span");
span.className = className;
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this)
});
}
}
return this.each(function() {
highlight(this);
});
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initModIndex();
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can savely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlight');
});
}, 10);
$('<li class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
.appendTo($('.sidebar .this-page-menu'));
}
},
/**
* init the modindex toggle buttons
*/
initModIndex : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
console.log($('tr.cg-' + idnum).toggle());
if (src.substr(-9) == 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
$('span.highlight').removeClass('highlight');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

View File

@ -1,61 +0,0 @@
.hll { background-color: #ffffcc }
.c { color: #408090; font-style: italic } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #007020; font-weight: bold } /* Keyword */
.o { color: #666666 } /* Operator */
.cm { color: #408090; font-style: italic } /* Comment.Multiline */
.cp { color: #007020 } /* Comment.Preproc */
.c1 { color: #408090; font-style: italic } /* Comment.Single */
.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #303030 } /* Generic.Output */
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.kp { color: #007020 } /* Keyword.Pseudo */
.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.kt { color: #902000 } /* Keyword.Type */
.m { color: #208050 } /* Literal.Number */
.s { color: #4070a0 } /* Literal.String */
.na { color: #4070a0 } /* Name.Attribute */
.nb { color: #007020 } /* Name.Builtin */
.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.no { color: #60add5 } /* Name.Constant */
.nd { color: #555555; font-weight: bold } /* Name.Decorator */
.ni { color: #d55537; font-weight: bold } /* Name.Entity */
.ne { color: #007020 } /* Name.Exception */
.nf { color: #06287e } /* Name.Function */
.nl { color: #002070; font-weight: bold } /* Name.Label */
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.nt { color: #062873; font-weight: bold } /* Name.Tag */
.nv { color: #bb60d5 } /* Name.Variable */
.ow { color: #007020; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #208050 } /* Literal.Number.Float */
.mh { color: #208050 } /* Literal.Number.Hex */
.mi { color: #208050 } /* Literal.Number.Integer */
.mo { color: #208050 } /* Literal.Number.Oct */
.sb { color: #4070a0 } /* Literal.String.Backtick */
.sc { color: #4070a0 } /* Literal.String.Char */
.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.s2 { color: #4070a0 } /* Literal.String.Double */
.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.sh { color: #4070a0 } /* Literal.String.Heredoc */
.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.sx { color: #c65d09 } /* Literal.String.Other */
.sr { color: #235388 } /* Literal.String.Regex */
.s1 { color: #4070a0 } /* Literal.String.Single */
.ss { color: #517918 } /* Literal.String.Symbol */
.bp { color: #007020 } /* Name.Builtin.Pseudo */
.vc { color: #bb60d5 } /* Name.Variable.Class */
.vg { color: #bb60d5 } /* Name.Variable.Global */
.vi { color: #bb60d5 } /* Name.Variable.Instance */
.il { color: #208050 } /* Literal.Number.Integer.Long */

View File

@ -1,467 +0,0 @@
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words, hlwords is the list of normal, unstemmed
* words. the first one is used to find the occurance, the
* latter for highlighting it.
*/
jQuery.makeSearchSummary = function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
var i = textLower.indexOf(this.toLowerCase());
if (i > -1)
start = i;
});
start = Math.max(start - 120, 0);
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlight');
});
return rv;
}
/**
* Porter Stemmer
*/
var PorterStemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
/**
* Search Module
*/
var Search = {
_index : null,
_queued_query : null,
_pulse_status : -1,
init : function() {
var params = $.getQueryParameters();
if (params.q) {
var query = params.q[0];
$('input[name="q"]')[0].value = query;
this.performSearch(query);
}
},
/**
* Sets the index
*/
setIndex : function(index) {
var q;
this._index = index;
if ((q = this._queued_query) !== null) {
this._queued_query = null;
Search.query(q);
}
},
hasIndex : function() {
return this._index !== null;
},
deferQuery : function(query) {
this._queued_query = query;
},
stopPulse : function() {
this._pulse_status = 0;
},
startPulse : function() {
if (this._pulse_status >= 0)
return;
function pulse() {
Search._pulse_status = (Search._pulse_status + 1) % 4;
var dotString = '';
for (var i = 0; i < Search._pulse_status; i++)
dotString += '.';
Search.dots.text(dotString);
if (Search._pulse_status > -1)
window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something
*/
performSearch : function(query) {
// create the required interface elements
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
this.startPulse();
// index already loaded, the browser was quick!
if (this.hasIndex())
this.query(query);
else
this.deferQuery(query);
},
query : function(query) {
// stem the searchterms and add them to the
// correct list
var stemmer = new PorterStemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = query.split(/\s+/);
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
for (var i = 0; i < tmp.length; i++) {
// stem the word
var word = stemmer.stemWord(tmp[i]).toLowerCase();
// select the correct list
if (word[0] == '-') {
var toAppend = excluded;
word = word.substr(1);
}
else {
var toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$.contains(toAppend, word))
toAppend.push(word);
};
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
console.debug('SEARCH: searching for:');
console.info('required: ', searchterms);
console.info('excluded: ', excluded);
// prepare search
var filenames = this._index.filenames;
var titles = this._index.titles;
var terms = this._index.terms;
var descrefs = this._index.descrefs;
var modules = this._index.modules;
var desctypes = this._index.desctypes;
var fileMap = {};
var files = null;
var objectResults = [];
var regularResults = [];
$('#search-progress').empty();
// lookup as object
if (object != null) {
for (var module in modules) {
if (module.indexOf(object) > -1) {
fn = modules[module];
descr = _('module, in ') + titles[fn];
objectResults.push([filenames[fn], module, '#module-'+module, descr]);
}
}
for (var prefix in descrefs) {
for (var name in descrefs[prefix]) {
if (name.toLowerCase().indexOf(object) > -1) {
match = descrefs[prefix][name];
fullname = (prefix ? prefix + '.' : '') + name;
descr = desctypes[match[1]] + _(', in ') + titles[match[0]];
objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);
}
}
}
}
// sort results descending
objectResults.sort(function(a, b) {
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
});
// perform the search on the required terms
for (var i = 0; i < searchterms.length; i++) {
var word = searchterms[i];
// no match but word was a required one
if ((files = terms[word]) == null)
break;
if (files.length == undefined) {
files = [files];
}
// create the mapping
for (var j = 0; j < files.length; j++) {
var file = files[j];
if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
}
}
// now check if the files don't contain excluded terms
for (var file in fileMap) {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
// ensure that none of the excluded terms is in the
// search result.
for (var i = 0; i < excluded.length; i++) {
if (terms[excluded[i]] == file ||
$.contains(terms[excluded[i]] || [], file)) {
valid = false;
break;
}
}
// if we have still a valid result we can add it
// to the result list
if (valid)
regularResults.push([filenames[file], titles[file], '', null]);
}
// delete unused variables in order to not waste
// memory until list is retrieved completely
delete filenames, titles, terms;
// now sort the regular results descending by title
regularResults.sort(function(a, b) {
var left = a[1].toLowerCase();
var right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
});
// combine both
var results = regularResults.concat(objectResults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
listItem.append($('<a/>').attr(
'href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.get('_sources/' + item[0] + '.txt', function(data) {
listItem.append($.makeSearchSummary(data, searchterms, hlterms));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
}
}
$(document).ready(function() {
Search.init();
});

View File

@ -1,171 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>5. py/bin/ scripts &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="Contents" href="contents.html" />
<link rel="next" title="6. 1   py.xml: Lightweight and flexible xml/html generation" href="xml.html" />
<link rel="prev" title="4. py.code" href="code.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="xml.html" title="6. 1   py.xml: Lightweight and flexible xml/html generation"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="code.html" title="4. py.code"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" accesskey="U">Contents</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-bin-scripts">
<h1>5. <tt class="docutils literal"><span class="pre">py/bin/</span></tt> scripts<a class="headerlink" href="#py-bin-scripts" title="Permalink to this headline"></a></h1>
<p>The py-lib contains some scripts, most of which are
small ones (apart from <tt class="docutils literal"><span class="pre">py.test</span></tt>) that help during
the python development process. If working
from a svn-checkout of py lib you may add <tt class="docutils literal"><span class="pre">py/bin</span></tt>
to your shell <tt class="docutils literal"><span class="pre">PATH</span></tt> which should make the scripts
available on your command prompt.</p>
<div class="section" id="py-test">
<h2>5.1. <tt class="docutils literal"><span class="pre">py.test</span></tt><a class="headerlink" href="#py-test" title="Permalink to this headline"></a></h2>
<p>The <tt class="docutils literal"><span class="pre">py.test</span></tt> executable is the main entry point into the py-lib testing tool,
see the <a class="reference external" href="test.html">py.test documentation</a>.</p>
</div>
<div class="section" id="py-cleanup">
<h2>5.2. <tt class="docutils literal"><span class="pre">py.cleanup</span></tt><a class="headerlink" href="#py-cleanup" title="Permalink to this headline"></a></h2>
<p>Usage: <tt class="docutils literal"><span class="pre">py.cleanup</span> <span class="pre">[PATH]</span></tt></p>
<p>Delete pyc file recursively, starting from <tt class="docutils literal"><span class="pre">PATH</span></tt> (which defaults to the
current working directory). Don&#8217;t follow links and don&#8217;t recurse into
directories with a &#8220;.&#8221;.</p>
</div>
<div class="section" id="py-countloc">
<h2>5.3. <tt class="docutils literal"><span class="pre">py.countloc</span></tt><a class="headerlink" href="#py-countloc" title="Permalink to this headline"></a></h2>
<p>Usage: <tt class="docutils literal"><span class="pre">py.countloc</span> <span class="pre">[PATHS]</span></tt></p>
<p>Count (non-empty) lines of python code and number of python files recursively
starting from a <tt class="docutils literal"><span class="pre">PATHS</span></tt> given on the command line (starting from the current
working directory). Distinguish between test files and normal ones and report
them separately.</p>
</div>
<div class="section" id="py-lookup">
<h2>5.4. <tt class="docutils literal"><span class="pre">py.lookup</span></tt><a class="headerlink" href="#py-lookup" title="Permalink to this headline"></a></h2>
<p>Usage: <tt class="docutils literal"><span class="pre">py.lookup</span> <span class="pre">SEARCH_STRING</span> <span class="pre">[options]</span></tt></p>
<p>Looks recursively at Python files for a <tt class="docutils literal"><span class="pre">SEARCH_STRING</span></tt>, starting from the
present working directory. Prints the line, with the filename and line-number
prepended.</p>
</div>
<div class="section" id="py-rest">
<h2>5.5. <tt class="docutils literal"><span class="pre">py.rest</span></tt><a class="headerlink" href="#py-rest" title="Permalink to this headline"></a></h2>
<p>Usage: <tt class="docutils literal"><span class="pre">py.rest</span> <span class="pre">[PATHS]</span> <span class="pre">[options]</span></tt></p>
<p>Loot recursively for .txt files starting from <tt class="docutils literal"><span class="pre">PATHS</span></tt> and convert them to
html using docutils or to pdf files, if the <tt class="docutils literal"><span class="pre">--pdf</span></tt> option is used. For
conversion to PDF you will need several command line tools, on Ubuntu Linux
this is <strong>texlive</strong> and <strong>texlive-extra-utils</strong>.</p>
<p><tt class="docutils literal"><span class="pre">py.rest</span></tt> has some extra features over rst2html (which is shipped with
docutils). Most of these are still experimental, the one which is most likely
not going to change is the <a class="reference external" href="http://www.graphviz.org">graphviz</a> directive. With that you can embed .dot
files into your document and have them be converted to png (when outputting
html) and to eps (when outputting pdf). Otherwise the directive works mostly
like the image directive:</p>
<div class="highlight-python"><pre>.. graphviz:: example.dot
:scale: 90</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">5. <tt class="docutils literal"><span class="pre">py/bin/</span></tt> scripts</a><ul>
<li><a class="reference external" href="#py-test">5.1. <tt class="docutils literal"><span class="pre">py.test</span></tt></a></li>
<li><a class="reference external" href="#py-cleanup">5.2. <tt class="docutils literal"><span class="pre">py.cleanup</span></tt></a></li>
<li><a class="reference external" href="#py-countloc">5.3. <tt class="docutils literal"><span class="pre">py.countloc</span></tt></a></li>
<li><a class="reference external" href="#py-lookup">5.4. <tt class="docutils literal"><span class="pre">py.lookup</span></tt></a></li>
<li><a class="reference external" href="#py-rest">5.5. <tt class="docutils literal"><span class="pre">py.rest</span></tt></a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="code.html"
title="previous chapter">4. py.code</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="xml.html"
title="next chapter">6. 1&nbsp;&nbsp;&nbsp;py.xml: Lightweight and flexible xml/html generation</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/bin.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="xml.html" title="6. 1   py.xml: Lightweight and flexible xml/html generation"
>next</a> |</li>
<li class="right" >
<a href="code.html" title="4. py.code"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,247 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>4. py.code &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="5. py/bin/ scripts" href="bin.html" />
<link rel="prev" title="3. py.path" href="path.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="bin.html" title="5. py/bin/ scripts"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="path.html" title="3. py.path"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-code">
<h1>4. py.code<a class="headerlink" href="#py-code" title="Permalink to this headline"></a></h1>
<p>The <tt class="docutils literal"><span class="pre">py.code</span></tt> part of the &#8216;py lib&#8217; contains some functionality to help
dealing with Python code objects. Even though working with Python&#8217;s internal
code objects (as found on frames and callables) can be very powerful, it&#8217;s
usually also quite cumbersome, because the API provided by core Python is
relatively low level and not very accessible.</p>
<p>The <tt class="docutils literal"><span class="pre">py.code</span></tt> library tries to simplify accessing the code objects as well
as creating them. There is a small set of interfaces a user needs to deal with,
all nicely bundled together, and with a rich set of &#8216;Pythonic&#8217; functionality.</p>
<p>source: <tt class="docutils literal"><span class="pre">py/code/</span></tt></p>
<div class="section" id="contents-of-the-library">
<h2>4.1. Contents of the library<a class="headerlink" href="#contents-of-the-library" title="Permalink to this headline"></a></h2>
<p>Every object in the <tt class="docutils literal"><span class="pre">py.code</span></tt> library wraps a code Python object related
to code objects, source code, frames and tracebacks: the <tt class="docutils literal"><span class="pre">py.code.Code</span></tt>
class wraps code objects, <tt class="docutils literal"><span class="pre">py.code.Source</span></tt> source snippets,
<tt class="docutils literal"><span class="pre">py.code.Traceback</span></tt> exception tracebacks, <tt class="docutils literal"><span class="pre">py.code.Frame</span></tt> frame
objects (as found in e.g. tracebacks) and <tt class="docutils literal"><span class="pre">py.code.ExceptionInfo</span></tt> the
tuple provided by sys.exc_info() (containing exception and traceback
information when an exception occurs). Also in the library is a helper function
<tt class="docutils literal"><span class="pre">py.code.compile()</span></tt> that provides the same functionality as Python&#8217;s
built-in &#8216;compile()&#8217; function, but returns a wrapped code object.</p>
</div>
<div class="section" id="the-wrappers">
<h2>4.2. The wrappers<a class="headerlink" href="#the-wrappers" title="Permalink to this headline"></a></h2>
<div class="section" id="py-code-code">
<h3>4.2.1. <tt class="docutils literal"><span class="pre">py.code.Code</span></tt><a class="headerlink" href="#py-code-code" title="Permalink to this headline"></a></h3>
<p>Code objects are instantiated with a code object or a callable as argument,
and provide functionality to compare themselves with other Code objects, get to
the source file or its contents, create new Code objects from scratch, etc.</p>
<p>A quick example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Code</span><span class="p">(</span><span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="o">.</span><span class="n">read</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">c</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span>
<span class="go">&#39;common.py&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">source</span><span class="p">(),</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Source</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">source</span><span class="p">())</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)[</span><span class="mf">0</span><span class="p">]</span>
<span class="go">&quot;def read(self, mode=&#39;rb&#39;):&quot;</span>
</pre></div>
</div>
<p>source: <tt class="docutils literal"><span class="pre">py/code/code.py</span></tt></p>
</div>
<div class="section" id="py-code-source">
<h3>4.2.2. <tt class="docutils literal"><span class="pre">py.code.Source</span></tt><a class="headerlink" href="#py-code-source" title="Permalink to this headline"></a></h3>
<p>Source objects wrap snippets of Python source code, providing a simple yet
powerful interface to read, deindent, slice, compare, compile and manipulate
them, things that are not so easy in core Python.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">s</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Source</span><span class="p">(</span><span class="s">&quot;&quot;&quot;</span><span class="se">\</span>
<span class="gp">... </span><span class="s"> def foo():</span>
<span class="gp">... </span><span class="s"> print &quot;foo&quot;</span>
<span class="gp">... </span><span class="s">&quot;&quot;&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;def&#39;</span><span class="p">)</span> <span class="c"># automatic de-indentation!</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">s</span><span class="o">.</span><span class="n">isparseable</span><span class="p">()</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sub</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">getstatement</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span> <span class="c"># get the statement starting at line 1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">sub</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="c"># XXX why is the strip() required?!?</span>
<span class="go">&#39;print &quot;foo&quot;&#39;</span>
</pre></div>
</div>
<p>source: <tt class="docutils literal"><span class="pre">py/code/source.py</span></tt></p>
</div>
<div class="section" id="py-code-traceback">
<h3>4.2.3. <tt class="docutils literal"><span class="pre">py.code.Traceback</span></tt><a class="headerlink" href="#py-code-traceback" title="Permalink to this headline"></a></h3>
<p>Tracebacks are usually not very easy to examine, you need to access certain
somewhat hidden attributes of the traceback&#8217;s items (resulting in expressions
such as &#8216;fname = tb.tb_next.tb_frame.f_code.co_filename&#8217;). The Traceback
interface (and its TracebackItem children) tries to improve this.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="p">(</span><span class="mf">100</span><span class="p">)</span> <span class="c"># illegal argument</span>
<span class="gp">... </span><span class="k">except</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">exc</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">tb</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Traceback</span><span class="p">(</span><span class="n">tb</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">first</span> <span class="o">=</span> <span class="n">t</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span> <span class="c"># get the second entry (first is in this doc)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">first</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span> <span class="c"># second is in py/path/local.py</span>
<span class="go">&#39;local.py&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">first</span><span class="o">.</span><span class="n">statement</span><span class="p">,</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Source</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">first</span><span class="o">.</span><span class="n">statement</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;raise ValueError&#39;</span><span class="p">)</span>
<span class="go">True</span>
</pre></div>
</div>
<p>source: <tt class="docutils literal"><span class="pre">py/code/traceback2.py</span></tt></p>
</div>
<div class="section" id="py-code-frame">
<h3>4.2.4. <tt class="docutils literal"><span class="pre">py.code.Frame</span></tt><a class="headerlink" href="#py-code-frame" title="Permalink to this headline"></a></h3>
<p>Frame wrappers are used in <tt class="docutils literal"><span class="pre">py.code.Traceback</span></tt> items, and will usually not
directly be instantiated. They provide some nice methods to evaluate code
&#8216;inside&#8217; the frame (using the frame&#8217;s local variables), get to the underlying
code (frames have a code attribute that points to a <tt class="docutils literal"><span class="pre">py.code.Code</span></tt> object)
and examine the arguments.</p>
<p>Example (using the &#8216;first&#8217; TracebackItem instance created above):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">frame</span> <span class="o">=</span> <span class="n">first</span><span class="o">.</span><span class="n">frame</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">frame</span><span class="o">.</span><span class="n">code</span><span class="p">,</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Code</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">frame</span><span class="o">.</span><span class="n">eval</span><span class="p">(</span><span class="s">&#39;self&#39;</span><span class="p">),</span> <span class="n">py</span><span class="o">.</span><span class="n">__</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="o">.</span><span class="n">local</span><span class="o">.</span><span class="n">LocalPath</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">[</span><span class="n">namevalue</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">namevalue</span> <span class="ow">in</span> <span class="n">frame</span><span class="o">.</span><span class="n">getargs</span><span class="p">()]</span>
<span class="go">[&#39;cls&#39;, &#39;path&#39;]</span>
</pre></div>
</div>
</div>
<div class="section" id="py-code-exceptioninfo">
<h3>4.2.5. <tt class="docutils literal"><span class="pre">py.code.ExceptionInfo</span></tt><a class="headerlink" href="#py-code-exceptioninfo" title="Permalink to this headline"></a></h3>
<p>A wrapper around the tuple returned by sys.exc_info() (will call sys.exc_info()
itself if the tuple is not provided as an argument), provides some handy
attributes to easily access the traceback and exception string.</p>
<p>Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">foobar</span><span class="p">()</span>
<span class="gp">... </span><span class="k">except</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">excinfo</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">ExceptionInfo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">excinfo</span><span class="o">.</span><span class="n">typename</span>
<span class="go">&#39;NameError&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">isinstance</span><span class="p">(</span><span class="n">excinfo</span><span class="o">.</span><span class="n">traceback</span><span class="p">,</span> <span class="n">py</span><span class="o">.</span><span class="n">code</span><span class="o">.</span><span class="n">Traceback</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">excinfo</span><span class="o">.</span><span class="n">exconly</span><span class="p">()</span>
<span class="go">&quot;NameError: name &#39;foobar&#39; is not defined&quot;</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">4. py.code</a><ul>
<li><a class="reference external" href="#contents-of-the-library">4.1. Contents of the library</a></li>
<li><a class="reference external" href="#the-wrappers">4.2. The wrappers</a><ul>
<li><a class="reference external" href="#py-code-code">4.2.1. <tt class="docutils literal"><span class="pre">py.code.Code</span></tt></a></li>
<li><a class="reference external" href="#py-code-source">4.2.2. <tt class="docutils literal"><span class="pre">py.code.Source</span></tt></a></li>
<li><a class="reference external" href="#py-code-traceback">4.2.3. <tt class="docutils literal"><span class="pre">py.code.Traceback</span></tt></a></li>
<li><a class="reference external" href="#py-code-frame">4.2.4. <tt class="docutils literal"><span class="pre">py.code.Frame</span></tt></a></li>
<li><a class="reference external" href="#py-code-exceptioninfo">4.2.5. <tt class="docutils literal"><span class="pre">py.code.ExceptionInfo</span></tt></a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="path.html"
title="previous chapter">3. py.path</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="bin.html"
title="next chapter">5. <tt class="docutils literal"><span class="pre">py/bin/</span></tt> scripts</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/code.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="bin.html" title="5. py/bin/ scripts"
>next</a> |</li>
<li class="right" >
<a href="path.html" title="3. py.path"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,153 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>12. Coding Style for the Py lib and friendly applications &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="coding-style-for-the-py-lib-and-friendly-applications">
<h1>12. Coding Style for the Py lib and friendly applications<a class="headerlink" href="#coding-style-for-the-py-lib-and-friendly-applications" title="Permalink to this headline"></a></h1>
<div class="section" id="honour-pep-8-style-guide-for-python-code">
<h2>12.1. Honour PEP 8: Style Guide for Python Code<a class="headerlink" href="#honour-pep-8-style-guide-for-python-code" title="Permalink to this headline"></a></h2>
<p>First of all, if you haven&#8217;t already read it, read the <a class="reference external" href="http://www.python.org/peps/pep-0008.html">PEP 8
Style Guide for Python Code</a> which, if in doubt, serves as
the default coding-style for the py lib.</p>
</div>
<div class="section" id="documentation-and-testing">
<h2>12.2. Documentation and Testing<a class="headerlink" href="#documentation-and-testing" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>generally we want to drive and interweave coding of
documentation, tests and real code as much as possible.
Without good documentation others may never know about
your latest and greatest feature.</li>
</ul>
</div>
<div class="section" id="naming">
<h2>12.3. naming<a class="headerlink" href="#naming" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>directories, modules and namespaces are always <strong>lowercase</strong></li>
<li>classes and especially Exceptions are most often <strong>CamelCase</strong></li>
<li>types, i.e. very widely usable classes like the <tt class="docutils literal"><span class="pre">py.path</span></tt>
family are all lower case.</li>
<li>never use plural names in directory and file names</li>
<li>functions/methods are lowercase and <tt class="docutils literal"><span class="pre">_</span></tt> - separated if
you really need to separate at all</li>
<li>it&#8217;s appreciated if you manage to name files in a directory
so that tab-completion on the shell level is as easy as possible.</li>
</ul>
</div>
<div class="section" id="committing">
<h2>12.4. committing<a class="headerlink" href="#committing" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>adding features requires adding appropriate tests.</li>
<li>bug fixes should be encoded in a test before being fixed.</li>
<li>write telling log messages because several people
will read your diffs, and we plan to have a search facility
over the py lib&#8217;s subversion repository.</li>
<li>if you add <tt class="docutils literal"><span class="pre">.txt</span></tt> or <tt class="docutils literal"><span class="pre">.py</span></tt> files to the repository then
please make sure you have <tt class="docutils literal"><span class="pre">svn:eol-style</span></tt> set to native.
which allows checkin/checkout in native line-ending format.</li>
</ul>
</div>
<div class="section" id="miscellaneous">
<h2>12.5. Miscellaneous<a class="headerlink" href="#miscellaneous" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Tests are the insurance that your code will be maintained
further and survives major releases.</li>
<li>Try to put the tests close to the tested code, don&#8217;t
overload directories with names.</li>
<li>If you think of exporting new py lib APIs, discuss it first on the
<a class="reference external" href="http://codespeak.net/mailman/listinfo/py-dev">py-dev mailing list</a> and possibly write a chapter in our
<cite>future_</cite> book. Communication is considered a key here to make
sure that the py lib develops in a consistent way.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">12. Coding Style for the Py lib and friendly applications</a><ul>
<li><a class="reference external" href="#honour-pep-8-style-guide-for-python-code">12.1. Honour PEP 8: Style Guide for Python Code</a></li>
<li><a class="reference external" href="#documentation-and-testing">12.2. Documentation and Testing</a></li>
<li><a class="reference external" href="#naming">12.3. naming</a></li>
<li><a class="reference external" href="#committing">12.4. committing</a></li>
<li><a class="reference external" href="#miscellaneous">12.5. Miscellaneous</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/coding-style.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,115 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>14. Contact and communication &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="15. Downloading" href="download.html" />
<link rel="prev" title="13. Links" href="links.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="download.html" title="15. Downloading"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="links.html" title="13. Links"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="contact-and-communication">
<h1>14. Contact and communication<a class="headerlink" href="#contact-and-communication" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><strong>#pylib on irc.freenode.net</strong>: you are welcome to lurk or ask questions!</li>
<li><a class="reference external" href="http://codespeak.net/mailman/listinfo/py-dev">py-dev developers list</a> development mailing list.</li>
<li><a class="reference external" href="http://tetamap.wordpress.com">tetamap</a>: Holger Krekel&#8217;s blog, often about testing and py.test related news.</li>
<li><a class="reference external" href="http://codespeak.net/mailman/listinfo/py-svn">py-svn general commit mailing list</a> to follow all development commits.</li>
<li><a class="reference external" href="https://codespeak.net/issue/py-dev/">development bug/feature tracker</a> this roundup instance serves to file bugs and track issues.
(soon to be substitued by a google-code or other hosted one).</li>
<li><a class="reference external" href="http://merlinux.eu">merlinux.eu</a> offers teaching and consulting services.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="links.html"
title="previous chapter">13. Links</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="download.html"
title="next chapter">15. Downloading</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/contact.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="download.html" title="15. Downloading"
>next</a> |</li>
<li class="right" >
<a href="links.html" title="13. Links"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,184 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<p>Contents:</p>
<ul>
<li class="toctree-l1"><a class="reference external" href="test.html">1. py.test</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-quickstart.html">1.1. Quickstart</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html">1.2. Features</a></li>
<li class="toctree-l2"><a class="reference external" href="test-plugins.html">1.3. Included plugins</a></li>
<li class="toctree-l2"><a class="reference external" href="test-ext.html">1.4. Writing plugins</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html">1.5. Distributed testing</a></li>
<li class="toctree-l2"><a class="reference external" href="test-config.html">1.6. Test configuration</a></li>
<li class="toctree-l2"><a class="reference external" href="test-examples.html">1.7. Working Examples</a></li>
<li class="toctree-l2"><a class="reference external" href="impl-test.html">1.8. Implementation and Customization of <tt class="docutils literal"><span class="pre">py.test</span></tt></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="execnet.html">2. py.execnet</a><ul>
<li class="toctree-l2"><a class="reference external" href="execnet.html#gateways-immediately-spawn-local-or-remote-process">2.1. Gateways: immediately spawn local or remote process</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#remote-exec-execute-source-code-remotely">2.2. remote_exec: execute source code remotely</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#channels-bidirectionally-exchange-data-between-hosts">2.3. Channels: bidirectionally exchange data between hosts</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#xspec-string-specification-for-gateway-type-and-configuration">2.4. XSpec: string specification for gateway type and configuration</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#examples-of-py-execnet-usage">2.5. Examples of py.execnet usage</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="path.html">3. py.path</a><ul>
<li class="toctree-l2"><a class="reference external" href="path.html#path-implementations-provided-by-py-path">3.1. Path implementations provided by <tt class="docutils literal"><span class="pre">py.path</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#common-vs-specific-api">3.2. Common vs. specific API</a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#known-problems-limitations">3.3. Known problems / limitations</a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#future-plans">3.4. Future plans</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="code.html">4. py.code</a><ul>
<li class="toctree-l2"><a class="reference external" href="code.html#contents-of-the-library">4.1. Contents of the library</a></li>
<li class="toctree-l2"><a class="reference external" href="code.html#the-wrappers">4.2. The wrappers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="bin.html">5. <tt class="docutils literal"><span class="pre">py/bin/</span></tt> scripts</a><ul>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-test">5.1. <tt class="docutils literal"><span class="pre">py.test</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-cleanup">5.2. <tt class="docutils literal"><span class="pre">py.cleanup</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-countloc">5.3. <tt class="docutils literal"><span class="pre">py.countloc</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-lookup">5.4. <tt class="docutils literal"><span class="pre">py.lookup</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-rest">5.5. <tt class="docutils literal"><span class="pre">py.rest</span></tt></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="xml.html">6. py.xml: Lightweight and flexible xml/html generation</a><ul>
<li class="toctree-l2"><a class="reference external" href="xml.html#motivation">6.1. Motivation</a></li>
<li class="toctree-l2"><a class="reference external" href="xml.html#a-pythonic-object-model-please">6.2. a pythonic object model , please</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="io.html">7. py.io</a><ul>
<li class="toctree-l2"><a class="reference external" href="io.html#io-capturing-examples">7.1. IO Capturing examples</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="log.html">8. py.log documentation and musings</a><ul>
<li class="toctree-l2"><a class="reference external" href="log.html#foreword">8.1. Foreword</a></li>
<li class="toctree-l2"><a class="reference external" href="log.html#logging-organisation">8.2. Logging organisation</a></li>
<li class="toctree-l2"><a class="reference external" href="log.html#using-the-py-log-library">8.3. Using the py.log library</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="misc.html">9. Miscellaneous features of the py lib</a><ul>
<li class="toctree-l2"><a class="reference external" href="misc.html#mapping-the-standard-python-library-into-py">9.1. Mapping the standard python library into py</a></li>
<li class="toctree-l2"><a class="reference external" href="misc.html#support-for-interaction-with-system-utilities-binaries">9.2. Support for interaction with system utilities/binaries</a></li>
<li class="toctree-l2"><a class="reference external" href="misc.html#cross-python-version-compatibility-helpers">9.3. Cross-Python Version compatibility helpers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="why_py.html">10. Why, who, what and how do you do <em>the py lib</em>?</a><ul>
<li class="toctree-l2"><a class="reference external" href="why_py.html#why-did-we-start-the-py-lib">10.1. Why did we start the py lib?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#what-is-the-py-libs-current-focus">10.2. What is the py libs current focus?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#how-does-py-development-work">10.3. How does py development work?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#who-is-we">10.4. Who is &#8220;we&#8221;?</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="future.html">11. Visions and ideas for further development of the py lib</a><ul>
<li class="toctree-l2"><a class="reference external" href="future.html#distribute-tests-ad-hoc-across-multiple-platforms">11.1. Distribute tests ad-hoc across multiple platforms</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#make-apigen-useful-for-more-projects">11.2. Make APIGEN useful for more projects</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#consider-apigen-and-pdb-integration">11.3. Consider APIGEN and pdb integration</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#distribute-channels-programs-across-networks">11.4. Distribute channels/programs across networks</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#benchmarking-and-persistent-storage">11.5. Benchmarking and persistent storage</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#refactor-path-implementations-to-use-a-filesystem-abstraction">11.6. Refactor path implementations to use a Filesystem Abstraction</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#integrate-interactive-completion">11.7. Integrate interactive completion</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#consider-more-features">11.8. Consider more features</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="coding-style.html">12. Coding Style for the Py lib and friendly applications</a><ul>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#honour-pep-8-style-guide-for-python-code">12.1. Honour PEP 8: Style Guide for Python Code</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#documentation-and-testing">12.2. Documentation and Testing</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#naming">12.3. naming</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#committing">12.4. committing</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#miscellaneous">12.5. Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="download.html">13. &#8220;easy_install py&#8221;</a></li>
<li class="toctree-l1"><a class="reference external" href="download.html#installing-on-debian-or-fedora">14. Installing on Debian or Fedora</a></li>
<li class="toctree-l1"><a class="reference external" href="download.html#downloading-a-tar-zip-archive-and-installing-that">15. Downloading a tar/zip archive and installing that</a></li>
<li class="toctree-l1"><a class="reference external" href="download.html#installing-from-subversion-develop-mode">16. Installing from subversion / develop mode</a></li>
<li class="toctree-l1"><a class="reference external" href="download.html#working-with-multiple-py-lib-versions-svn-externals">17. Working with multiple py lib versions / svn externals</a></li>
<li class="toctree-l1"><a class="reference external" href="links.html">18. Links</a></li>
<li class="toctree-l1"><a class="reference external" href="contact.html">19. py lib contact and communication</a></li>
</ul>
<ul class="simple">
<li><a class="reference external" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference external" href="modindex.html"><em>Module Index</em></a></li>
<li><a class="reference external" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/contents.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,203 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>15. Downloading &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="16. Release notes" href="releases.html" />
<link rel="prev" title="14. Contact and communication" href="contact.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="releases.html" title="16. Release notes"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="contact.html" title="14. Contact and communication"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="downloading">
<h1>15. Downloading<a class="headerlink" href="#downloading" title="Permalink to this headline"></a></h1>
<div class="section" id="easy-install-py">
<h2>15.1. &#8220;easy_install py&#8221;<a class="headerlink" href="#easy-install-py" title="Permalink to this headline"></a></h2>
<p>With a working <a class="reference external" href="http://pypi.python.org/pypi/setuptools">setuptools installation</a> you can install from the command line:</p>
<div class="highlight-python"><pre>easy_install -U py</pre>
</div>
<p>to get the latest release of the py lib. The <tt class="docutils literal"><span class="pre">-U</span></tt> switch
will trigger an upgrade if you already have an older version installed.
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.</p>
<p>We provide binary eggs for Windows machines.</p>
<p>On other systems you need a working C-compiler in order to
install the full py lib. If you don&#8217;t have a compiler available
you can still install the py lib but without greenlets - look
below for the <tt class="docutils literal"><span class="pre">install_lib</span></tt> target.</p>
<p><strong>IMPORTANT NOTE</strong>: if you are using Windows and have previous
installations of the py lib on your system, please download
and execute <a class="reference external" href="http://codespeak.net/svn/py/build/winpathclean.py">http://codespeak.net/svn/py/build/winpathclean.py</a>
This will check that no previous files are getting in the way.
(Unfortunately we don&#8217;t know about a way to execute this
code automatically during the above install).</p>
</div>
<div class="section" id="installing-on-debian-or-fedora">
<h2>15.2. Installing on Debian or Fedora<a class="headerlink" href="#installing-on-debian-or-fedora" title="Permalink to this headline"></a></h2>
<p>On Debian systems look for <tt class="docutils literal"><span class="pre">python-codespeak-lib</span></tt>.
<em>This package is probably outdated - if somebody
can help with bringing this up to date,
that would be very much appreciated.</em></p>
<p>Dwayne Bailey has thankfully put together a Fedora <a class="reference external" href="http://translate.sourceforge.net/releases/testing/fedora/pylib-0.9.2-1.fc9.noarch.rpm">RPM</a>.</p>
</div>
<div class="section" id="downloading-a-tar-zip-archive-and-installing-that">
<h2>15.3. Downloading a tar/zip archive and installing that<a class="headerlink" href="#downloading-a-tar-zip-archive-and-installing-that" title="Permalink to this headline"></a></h2>
<p>Go to the python package index (pypi) and download a tar or zip file:</p>
<blockquote>
<a class="reference external" href="http://pypi.python.org/pypi/py/">http://pypi.python.org/pypi/py/</a></blockquote>
<p>and unpack it to a directory, where you then type:</p>
<div class="highlight-python"><pre>python setup.py install</pre>
</div>
<p>If you don&#8217;t have a working C-compiler you can do:</p>
<div class="highlight-python"><pre>python setup.py install_lib</pre>
</div>
<p>You will then not be able to use greenlets but otherwise
<tt class="docutils literal"><span class="pre">py.test</span></tt> and all tools and APIs are fine to use.</p>
</div>
<div class="section" id="installing-from-subversion-develop-mode">
<h2>15.4. Installing from subversion / develop mode<a class="headerlink" href="#installing-from-subversion-develop-mode" title="Permalink to this headline"></a></h2>
<p>To follow development or help with fixing things
for the next release, checkout the complete code
and documentation source:</p>
<div class="highlight-python"><pre>svn co http://codespeak.net/svn/py/release/0.9.x py-0.9.x</pre>
</div>
<p>You can then issue:</p>
<div class="highlight-python"><pre>python setup.py develop</pre>
</div>
<p>in order to work with your checkout version.</p>
<p>other interesting svn checkout points:</p>
<div class="highlight-python"><pre>http://codespeak.net/
svn/py/release # release tags and branches
svn/py/dist # latest stable (may or may not be a release)
svn/py/trunk # head development / merge point</pre>
</div>
</div>
<div class="section" id="working-with-multiple-py-lib-versions-svn-externals">
<h2>15.5. Working with multiple py lib versions / svn externals<a class="headerlink" href="#working-with-multiple-py-lib-versions-svn-externals" title="Permalink to this headline"></a></h2>
<p>If you happen to have multiple versions of the py lib
around or you ship the py lib as an svn-external to
then you might want to use py lib scripts more directly.
For example if you have a project layout like this:</p>
<div class="highlight-python"><pre>mypkg/
subpkg1/
tests/
tests/
py/ # as svn-external, could be specific tag/version</pre>
</div>
<p>then you want to make sure that the actual local py lib is used
and not another system-wide version. For this you need to add
<tt class="docutils literal"><span class="pre">py/bin</span></tt> or <tt class="docutils literal"><span class="pre">py\bin\win32</span></tt> respectively to your system&#8217;s PATH settings.</p>
<p>You can do this by executing (on windows) a script to set the environment:</p>
<div class="highlight-python"><pre>c:\\path\to\checkout\py\env.cmd</pre>
</div>
<p>or on linux/osx you can add something like this to your shell
initialization:</p>
<div class="highlight-python"><pre>eval `python ~/path/to/checkout/py/env.py`</pre>
</div>
<p>to get good settings for PYTHONPATH and PATH.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">15. Downloading</a><ul>
<li><a class="reference external" href="#easy-install-py">15.1. &#8220;easy_install py&#8221;</a></li>
<li><a class="reference external" href="#installing-on-debian-or-fedora">15.2. Installing on Debian or Fedora</a></li>
<li><a class="reference external" href="#downloading-a-tar-zip-archive-and-installing-that">15.3. Downloading a tar/zip archive and installing that</a></li>
<li><a class="reference external" href="#installing-from-subversion-develop-mode">15.4. Installing from subversion / develop mode</a></li>
<li><a class="reference external" href="#working-with-multiple-py-lib-versions-svn-externals">15.5. Working with multiple py lib versions / svn externals</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="contact.html"
title="previous chapter">14. Contact and communication</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="releases.html"
title="next chapter">16. Release notes</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/download.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="releases.html" title="16. Release notes"
>next</a> |</li>
<li class="right" >
<a href="contact.html" title="14. Contact and communication"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,340 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>2. py.execnet &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="3. py.path" href="path.html" />
<link rel="prev" title="1.7. Working Examples" href="test-examples.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="path.html" title="3. py.path"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-execnet">
<h1>2. py.execnet<a class="headerlink" href="#py-execnet" title="Permalink to this headline"></a></h1>
<p><tt class="docutils literal"><span class="pre">py.execnet</span></tt> allows to:</p>
<ul class="simple">
<li>instantiate local or remote Python Processes</li>
<li>send code for execution in one or many processes</li>
<li>asynchronously send and receive data between processes through channels</li>
<li>completely avoid manual installation steps on remote places</li>
</ul>
<div class="section" id="gateways-immediately-spawn-local-or-remote-process">
<h2>2.1. Gateways: immediately spawn local or remote process<a class="headerlink" href="#gateways-immediately-spawn-local-or-remote-process" title="Permalink to this headline"></a></h2>
<p>In order to send code to a remote place or a subprocess
you need to instantiate a so-called Gateway object.
There are currently three Gateway classes:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">py.execnet.PopenGateway</span></tt> to open a subprocess
on the local machine. Useful for making use
of multiple processors to to contain code execution
in a separated environment.</li>
<li><tt class="docutils literal"><span class="pre">py.execnet.SshGateway</span></tt> to connect to
a remote ssh server and distribute execution to it.</li>
<li><tt class="docutils literal"><span class="pre">py.execnet.SocketGateway</span></tt> a way to connect to
a remote Socket based server. <em>Note</em> that this method
requires a manually started
:source:py/execnet/script/socketserver.py
script. You can run this &#8220;server script&#8221; without
having the py lib installed on the remote system
and you can setup it up as permanent service.</li>
</ul>
</div>
<div class="section" id="remote-exec-execute-source-code-remotely">
<h2>2.2. remote_exec: execute source code remotely<a class="headerlink" href="#remote-exec-execute-source-code-remotely" title="Permalink to this headline"></a></h2>
<p>All gateways offer remote code execution via this high level function:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">remote_exec</span><span class="p">(</span><span class="n">source</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;return channel object for communicating with the asynchronously</span>
<span class="sd"> executing &#39;source&#39; code which will have a corresponding &#39;channel&#39;</span>
<span class="sd"> object in its executing namespace.&quot;&quot;&quot;</span>
</pre></div>
</div>
<p>With <cite>remote_exec</cite> you send source code to the other
side and get both a local and a remote <a class="reference internal" href="#channel">Channel</a> object,
which you can use to have the local and remote site
communicate data in a structured way. Here is
an example for reading the PID:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">gw</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">channel</span> <span class="o">=</span> <span class="n">gw</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;&quot;&quot;</span>
<span class="gp">... </span><span class="s"> import os</span>
<span class="gp">... </span><span class="s"> channel.send(os.getpid())</span>
<span class="gp">... </span><span class="s">&quot;&quot;&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">remote_pid</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">receive</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">remote_pid</span> <span class="o">!=</span> <span class="n">py</span><span class="o">.</span><span class="n">std</span><span class="o">.</span><span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="channels-bidirectionally-exchange-data-between-hosts">
<span id="exchange-data"></span><span id="channel-api"></span><span id="channel"></span><h2>2.3. Channels: bidirectionally exchange data between hosts<a class="headerlink" href="#channels-bidirectionally-exchange-data-between-hosts" title="Permalink to this headline"></a></h2>
<p>A channel object allows to send and receive data between
two asynchronously running programs. When calling
<cite>remote_exec</cite> you will get a channel object back and
the code fragment running on the other side will
see a channel object in its global namespace.</p>
<p>Here is the interface of channel objects:</p>
<div class="highlight-python"><pre>#
# API for sending and receiving anonymous values
#
channel.send(item):
sends the given item to the other side of the channel,
possibly blocking if the sender queue is full.
Note that items need to be marshallable (all basic
python types are).
channel.receive():
receives an item that was sent from the other side,
possibly blocking if there is none.
Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.waitclose(timeout=None):
wait until this channel is closed. Note that a closed
channel may still hold items that will be received or
send. Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.close():
close this channel on both the local and the remote side.
A remote side blocking on receive() on this channel
will get woken up and see an EOFError exception.</pre>
</div>
</div>
<div class="section" id="xspec-string-specification-for-gateway-type-and-configuration">
<span id="xspec"></span><h2>2.4. XSpec: string specification for gateway type and configuration<a class="headerlink" href="#xspec-string-specification-for-gateway-type-and-configuration" title="Permalink to this headline"></a></h2>
<p><tt class="docutils literal"><span class="pre">py.execnet</span></tt> supports a simple extensible format for
specifying and configuring Gateways for remote execution.
You can use a string specification to instantiate a new gateway,
for example a new SshGateway:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">gateway</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">makegateway</span><span class="p">(</span><span class="s">&quot;ssh=myhost&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Let&#8217;s look at some examples for valid specifications.
Specification for an ssh connection to <cite>wyvern</cite>, running on python2.4 in the (newly created) &#8216;mycache&#8217; subdirectory:</p>
<div class="highlight-python"><pre>ssh=wyvern//python=python2.4//chdir=mycache</pre>
</div>
<p>Specification of a python2.5 subprocess; with a low CPU priority (&#8220;nice&#8221; level). Current dir will be the current dir of the instantiator (that&#8217;s true for all &#8216;popen&#8217; specifications unless they specify &#8216;chdir&#8217;):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">popen</span><span class="o">//</span><span class="n">python</span><span class="o">=</span><span class="mf">2.5</span><span class="o">//</span><span class="n">nice</span><span class="o">=</span><span class="mf">20</span>
</pre></div>
</div>
<p>Specification of a Python Socket server process that listens on 192.168.1.4:8888; current dir will be the &#8216;pyexecnet-cache&#8217; sub directory which is used a default for all remote processes:</p>
<div class="highlight-python"><pre>socket=192.168.1.4:8888</pre>
</div>
<p>More generally, a specification string has this general format:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">key1</span><span class="o">=</span><span class="n">value1</span><span class="o">//</span><span class="n">key2</span><span class="o">=</span><span class="n">value2</span><span class="o">//</span><span class="n">key3</span><span class="o">=</span><span class="n">value3</span>
</pre></div>
</div>
<p>If you omit a value, a boolean true value is assumed. Currently
the following key/values are supported:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">popen</span></tt> for a PopenGateway</li>
<li><tt class="docutils literal"><span class="pre">ssh=host</span></tt> for a SshGateway</li>
<li><tt class="docutils literal"><span class="pre">socket=address:port</span></tt> for a SocketGateway</li>
<li><tt class="docutils literal"><span class="pre">python=executable</span></tt> for specifying Python executables</li>
<li><tt class="docutils literal"><span class="pre">chdir=path</span></tt> change remote working dir to given relative or absolute path</li>
<li><tt class="docutils literal"><span class="pre">nice=value</span></tt> decrease remote nice level if platforms supports it</li>
</ul>
</div>
<div class="section" id="examples-of-py-execnet-usage">
<h2>2.5. Examples of py.execnet usage<a class="headerlink" href="#examples-of-py-execnet-usage" title="Permalink to this headline"></a></h2>
<div class="section" id="compare-cwd-of-popen-gateways">
<h3>2.5.1. Compare cwd() of Popen Gateways<a class="headerlink" href="#compare-cwd-of-popen-gateways" title="Permalink to this headline"></a></h3>
<p>A PopenGateway has the same working directory as the instantiatior:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span><span class="o">,</span> <span class="nn">os</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">gw</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ch</span> <span class="o">=</span> <span class="n">gw</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;import os; channel.send(os.getcwd())&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">res</span> <span class="o">=</span> <span class="n">ch</span><span class="o">.</span><span class="n">receive</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">res</span> <span class="o">==</span> <span class="n">os</span><span class="o">.</span><span class="n">getcwd</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">gw</span><span class="o">.</span><span class="n">exit</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="synchronously-receive-results-from-two-sub-processes">
<h3>2.5.2. Synchronously receive results from two sub processes<a class="headerlink" href="#synchronously-receive-results-from-two-sub-processes" title="Permalink to this headline"></a></h3>
<p>Use MultiChannels for receiving multiple results from remote code:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ch1</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;channel.send(1)&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ch2</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;channel.send(2)&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mch</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">MultiChannel</span><span class="p">([</span><span class="n">ch1</span><span class="p">,</span> <span class="n">ch2</span><span class="p">])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">l</span> <span class="o">=</span> <span class="n">mch</span><span class="o">.</span><span class="n">receive_each</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> <span class="o">==</span> <span class="mf">2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="mf">1</span> <span class="ow">in</span> <span class="n">l</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="mf">2</span> <span class="ow">in</span> <span class="n">l</span>
</pre></div>
</div>
</div>
<div class="section" id="asynchronously-receive-results-from-two-sub-processes">
<h3>2.5.3. Asynchronously receive results from two sub processes<a class="headerlink" href="#asynchronously-receive-results-from-two-sub-processes" title="Permalink to this headline"></a></h3>
<p>Use <tt class="docutils literal"><span class="pre">MultiChannel.make_receive_queue()</span></tt> for asynchronously receiving
multiple results from remote code. This standard Queue provides
<tt class="docutils literal"><span class="pre">(channel,</span> <span class="pre">result)</span></tt> tuples which allows to determine where
a result comes from:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ch1</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;channel.send(1)&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">ch2</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;channel.send(2)&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mch</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">MultiChannel</span><span class="p">([</span><span class="n">ch1</span><span class="p">,</span> <span class="n">ch2</span><span class="p">])</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">queue</span> <span class="o">=</span> <span class="n">mch</span><span class="o">.</span><span class="n">make_receive_queue</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">chan1</span><span class="p">,</span> <span class="n">res1</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> <span class="c"># you may also specify a timeout</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">chan2</span><span class="p">,</span> <span class="n">res2</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">res1</span> <span class="o">+</span> <span class="n">res2</span>
<span class="go">3</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">chan1</span> <span class="ow">in</span> <span class="p">(</span><span class="n">ch1</span><span class="p">,</span> <span class="n">ch2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">chan2</span> <span class="ow">in</span> <span class="p">(</span><span class="n">ch1</span><span class="p">,</span> <span class="n">ch2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">chan1</span> <span class="o">!=</span> <span class="n">chan2</span>
</pre></div>
</div>
</div>
<div class="section" id="receive-file-contents-from-remote-ssh-account">
<h3>2.5.4. Receive file contents from remote SSH account<a class="headerlink" href="#receive-file-contents-from-remote-ssh-account" title="Permalink to this headline"></a></h3>
<p>Here is a small program that you can use to retrieve
contents of remote files:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">py</span>
<span class="c"># open a gateway to a fresh child process</span>
<span class="n">gw</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">SshGateway</span><span class="p">(</span><span class="s">&#39;codespeak.net&#39;</span><span class="p">)</span>
<span class="n">channel</span> <span class="o">=</span> <span class="n">gw</span><span class="o">.</span><span class="n">remote_exec</span><span class="p">(</span><span class="s">&quot;&quot;&quot;</span>
<span class="s"> for fn in channel:</span>
<span class="s"> f = open(fn, &#39;rb&#39;)</span>
<span class="s"> channel.send(f.read())</span>
<span class="s"> f.close()</span>
<span class="s">&quot;&quot;&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">fn</span> <span class="ow">in</span> <span class="n">somefilelist</span><span class="p">:</span>
<span class="n">channel</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">fn</span><span class="p">)</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">receive</span><span class="p">()</span>
<span class="c"># process content</span>
<span class="c"># later you can exit / close down the gateway</span>
<span class="n">gw</span><span class="o">.</span><span class="n">exit</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="instantiate-a-socket-server-in-a-new-subprocess">
<h3>2.5.5. Instantiate a socket server in a new subprocess<a class="headerlink" href="#instantiate-a-socket-server-in-a-new-subprocess" title="Permalink to this headline"></a></h3>
<p>The following example opens a PopenGateway, i.e. a python
child process, and starts a socket server within that process
and then opens a second gateway to the freshly started
socketserver:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">py</span>
<span class="n">popengw</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">PopenGateway</span><span class="p">()</span>
<span class="n">socketgw</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">execnet</span><span class="o">.</span><span class="n">SocketGateway</span><span class="o">.</span><span class="n">new_remote</span><span class="p">(</span><span class="n">popengw</span><span class="p">,</span> <span class="p">(</span><span class="s">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="mf">0</span><span class="p">))</span>
<span class="k">print</span> <span class="n">socketgw</span><span class="o">.</span><span class="n">_rinfo</span><span class="p">()</span> <span class="c"># print some info about the remote environment</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">2. py.execnet</a><ul>
<li><a class="reference external" href="#gateways-immediately-spawn-local-or-remote-process">2.1. Gateways: immediately spawn local or remote process</a></li>
<li><a class="reference external" href="#remote-exec-execute-source-code-remotely">2.2. remote_exec: execute source code remotely</a></li>
<li><a class="reference external" href="#channels-bidirectionally-exchange-data-between-hosts">2.3. Channels: bidirectionally exchange data between hosts</a></li>
<li><a class="reference external" href="#xspec-string-specification-for-gateway-type-and-configuration">2.4. XSpec: string specification for gateway type and configuration</a></li>
<li><a class="reference external" href="#examples-of-py-execnet-usage">2.5. Examples of py.execnet usage</a><ul>
<li><a class="reference external" href="#compare-cwd-of-popen-gateways">2.5.1. Compare cwd() of Popen Gateways</a></li>
<li><a class="reference external" href="#synchronously-receive-results-from-two-sub-processes">2.5.2. Synchronously receive results from two sub processes</a></li>
<li><a class="reference external" href="#asynchronously-receive-results-from-two-sub-processes">2.5.3. Asynchronously receive results from two sub processes</a></li>
<li><a class="reference external" href="#receive-file-contents-from-remote-ssh-account">2.5.4. Receive file contents from remote SSH account</a></li>
<li><a class="reference external" href="#instantiate-a-socket-server-in-a-new-subprocess">2.5.5. Instantiate a socket server in a new subprocess</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-examples.html"
title="previous chapter">1.7. Working Examples</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="path.html"
title="next chapter">3. py.path</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/execnet.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="path.html" title="3. py.path"
>next</a> |</li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,197 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>11. Visions and ideas for further development of the py lib &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="visions-and-ideas-for-further-development-of-the-py-lib">
<h1>11. Visions and ideas for further development of the py lib<a class="headerlink" href="#visions-and-ideas-for-further-development-of-the-py-lib" title="Permalink to this headline"></a></h1>
<p>This document tries to describe directions and guiding ideas
for the near-future development of the py lib. <em>Note that all
statements within this document - even if they sound factual -
mostly just express thoughts and ideas. They not always refer to
real code so read with some caution.</em></p>
<div class="section" id="distribute-tests-ad-hoc-across-multiple-platforms">
<h2>11.1. Distribute tests ad-hoc across multiple platforms<a class="headerlink" href="#distribute-tests-ad-hoc-across-multiple-platforms" title="Permalink to this headline"></a></h2>
<p>After some more refactoring and unification of
the current testing and distribution support code
we&#8217;d like to be able to run tests on multiple
platforms simultanously and allow for interaction
and introspection into the (remote) failures.</p>
</div>
<div class="section" id="make-apigen-useful-for-more-projects">
<h2>11.2. Make APIGEN useful for more projects<a class="headerlink" href="#make-apigen-useful-for-more-projects" title="Permalink to this headline"></a></h2>
<p>The new APIGEN tool offers rich information
derived from running tests against an application:
argument types and callsites, i.e. it shows
the places where a particular API is used.
In its first incarnation, there are still
some specialties that likely prevent it
from documenting APIs for other projects.
We&#8217;d like to evolve to a <cite>py.apigen</cite> tool
that can make use of information provided
by a py.test run.</p>
</div>
<div class="section" id="consider-apigen-and-pdb-integration">
<h2>11.3. Consider APIGEN and pdb integration<a class="headerlink" href="#consider-apigen-and-pdb-integration" title="Permalink to this headline"></a></h2>
<p>The information provided by APIGEN can be used in many
different ways. An example of this could be to write
an extension to pdb which makes it available.
Imagine you could issue a pdb command
&#8220;info &lt;function name&gt;&#8221; and get information
regarding incoming, and outgoing types, possible
exceptions, field types and call sites.</p>
</div>
<div class="section" id="distribute-channels-programs-across-networks">
<h2>11.4. Distribute channels/programs across networks<a class="headerlink" href="#distribute-channels-programs-across-networks" title="Permalink to this headline"></a></h2>
<p>Apart from stabilizing setup/teardown procedures
for <a class="reference external" href="execnet.html">py.execnet</a>, we&#8217;d like to generalize its
implementation to allow connecting two programs
across multiple hosts, i.e. we&#8217;d like to arbitrarily
send &#8220;channels&#8221; across the network. Likely this
will be done by using the &#8220;pipe&#8221; model, i.e.
that each channel is actually a pair of endpoints,
both of which can be independently transported
across the network. The programs who &#8220;own&#8221;
these endpoints remain connected.</p>
</div>
<div class="section" id="benchmarking-and-persistent-storage">
<h2>11.5. Benchmarking and persistent storage<a class="headerlink" href="#benchmarking-and-persistent-storage" title="Permalink to this headline"></a></h2>
<p>For storing test results, but also benchmarking
and other information, we need a solid way
to store all kinds of information from test runs.
We&#8217;d like to generate statistics or html-overview
out of it, but also use such information to determine when
a certain test broke, or when its performance
decreased considerably.</p>
</div>
<div class="section" id="refactor-path-implementations-to-use-a-filesystem-abstraction">
<span id="a-more-general-view-on-path-objects"></span><span id="general-path"></span><h2>11.6. Refactor path implementations to use a Filesystem Abstraction<a class="headerlink" href="#refactor-path-implementations-to-use-a-filesystem-abstraction" title="Permalink to this headline"></a></h2>
<p>It seems like a good idea to refactor all <a class="reference external" href="http://codespeak.net/py/dist/path.html">py.path</a> Path implementations to
use an internal Filesystem abstraction. The current code base
would be transformed to have Filesystem implementations for e.g.
local, subversion and subversion &#8220;working copy&#8221; filesystems. Today
the according code is scattered through path-handling code.</p>
<p>On a related note, Armin Rigo has hacked <a class="reference external" href="http://codespeak.net/svn/user/arigo/hack/pylufs/">pylufs</a> and more recently has
written <a class="reference external" href="http://codespeak.net/svn/user/arigo/hack/pyfuse/">pyfuse</a> which allow to
implement kernel-level linux filesystems with pure python. Now
the idea is that the mentioned filesystem implementations would
be directly usable for such linux-filesystem glue code.</p>
<p>In other words, implementing a <a class="reference external" href="http://codespeak.net/svn/user/arigo/hack/pyfuse/memoryfs.py">memoryfs</a> or a <a class="reference external" href="http://codespeak.net/pipermail/py-dev/2005-January/000191.html">dictfs</a> would
give you two things for free: a filesystem mountable at kernel level
as well as a uniform &#8220;path&#8221; object allowing you to access your
filesystem in convenient ways.</p>
<p>Also interesting to check out is Will McGugan&#8217;s work on
his <a class="reference external" href="http://www.willmcgugan.com/2008/09/21/announcing-fs-010-a-python-file-system/#comment-60276">fs package</a>.</p>
<p>I think the main question is what the very fundamental
filesystem API should look like. Here are some doctests
on how a <a class="reference external" href="draft_pyfs">draft py.fs</a> could look like. There also
is Matthew Scotts <a class="reference external" href="http://codespeak.net/pipermail/py-dev/attachments/20050128/d9595512/virtual1-0001.bin">dictproxy patch</a> which adds
<tt class="docutils literal"><span class="pre">py.path.dict</span></tt> and <tt class="docutils literal"><span class="pre">py.path.proxy</span></tt>.</p>
</div>
<div class="section" id="integrate-interactive-completion">
<h2>11.7. Integrate interactive completion<a class="headerlink" href="#integrate-interactive-completion" title="Permalink to this headline"></a></h2>
<p>It&#8217;d be nice to integrate the bash-like
<a class="reference external" href="http://codespeak.net/rlcompleter2/">rlcompleter2</a> python command line completer
into the py lib, and making it work remotely
and with pdb.</p>
</div>
<div class="section" id="consider-more-features">
<h2>11.8. Consider more features<a class="headerlink" href="#consider-more-features" title="Permalink to this headline"></a></h2>
<p>There are many more features and useful classes
that might be nice to integrate. For example, we might put
Armin&#8217;s <a class="reference external" href="http://codespeak.net/svn/user/arigo/hack/misc/collect.py">lazy list</a> implementation into the py lib.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">11. Visions and ideas for further development of the py lib</a><ul>
<li><a class="reference external" href="#distribute-tests-ad-hoc-across-multiple-platforms">11.1. Distribute tests ad-hoc across multiple platforms</a></li>
<li><a class="reference external" href="#make-apigen-useful-for-more-projects">11.2. Make APIGEN useful for more projects</a></li>
<li><a class="reference external" href="#consider-apigen-and-pdb-integration">11.3. Consider APIGEN and pdb integration</a></li>
<li><a class="reference external" href="#distribute-channels-programs-across-networks">11.4. Distribute channels/programs across networks</a></li>
<li><a class="reference external" href="#benchmarking-and-persistent-storage">11.5. Benchmarking and persistent storage</a></li>
<li><a class="reference external" href="#refactor-path-implementations-to-use-a-filesystem-abstraction">11.6. Refactor path implementations to use a Filesystem Abstraction</a></li>
<li><a class="reference external" href="#integrate-interactive-completion">11.7. Integrate interactive completion</a></li>
<li><a class="reference external" href="#consider-more-features">11.8. Consider more features</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/future.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,89 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="index">Index</h1>
<hr />
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="" title="General Index"
>index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,342 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.8. Implementation and Customization of py.test &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="2. py.execnet" href="execnet.html" />
<link rel="prev" title="1.7. Working Examples" href="test-examples.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="implementation-and-customization-of-py-test">
<h1>1.8. Implementation and Customization of <tt class="docutils literal"><span class="pre">py.test</span></tt><a class="headerlink" href="#implementation-and-customization-of-py-test" title="Permalink to this headline"></a></h1>
<div class="section" id="collecting-and-running-tests-implementation-remarks">
<span id="basicpicture"></span><h2>1.8.1. Collecting and running tests / implementation remarks<a class="headerlink" href="#collecting-and-running-tests-implementation-remarks" title="Permalink to this headline"></a></h2>
<p>In order to customize <tt class="docutils literal"><span class="pre">py.test</span></tt> it&#8217;s good to understand
its basic architure (WARNING: these are not guaranteed
yet to stay the way they are now!):</p>
<div class="highlight-python"><pre> ___________________
| |
| Collector |
|___________________|
/ \
| Item.run()
| ^
receive test Items /
| /execute test Item
| /
___________________/
| |
| Session |
|___________________|
.............................
. conftest.py configuration .
. cmdline options .
.............................</pre>
</div>
<p>The <em>Session</em> basically receives test <em>Items</em> from a <em>Collector</em>,
and executes them via the <tt class="docutils literal"><span class="pre">Item.run()</span></tt> method. It monitors
the outcome of the test and reports about failures and successes.</p>
<div class="section" id="collectors-and-the-test-collection-process">
<span id="collection-process"></span><h3>1.8.1.1. Collectors and the test collection process<a class="headerlink" href="#collectors-and-the-test-collection-process" title="Permalink to this headline"></a></h3>
<p>The collecting process is iterative, i.e. the session
traverses and generates a <em>collector tree</em>. Here is an example of such
a tree, generated with the command <tt class="docutils literal"><span class="pre">py.test</span> <span class="pre">--collectonly</span> <span class="pre">py/xmlobj</span></tt>:</p>
<div class="highlight-python"><pre>&lt;Directory 'xmlobj'&gt;
&lt;Directory 'testing'&gt;
&lt;Module 'test_html.py' (py.__.xmlobj.testing.test_html)&gt;
&lt;Function 'test_html_name_stickyness'&gt;
&lt;Function 'test_stylenames'&gt;
&lt;Function 'test_class_None'&gt;
&lt;Function 'test_alternating_style'&gt;
&lt;Module 'test_xml.py' (py.__.xmlobj.testing.test_xml)&gt;
&lt;Function 'test_tag_with_text'&gt;
&lt;Function 'test_class_identity'&gt;
&lt;Function 'test_tag_with_text_and_attributes'&gt;
&lt;Function 'test_tag_with_subclassed_attr_simple'&gt;
&lt;Function 'test_tag_nested'&gt;
&lt;Function 'test_tag_xmlname'&gt;</pre>
</div>
<p>By default all directories not starting with a dot are traversed,
looking for <tt class="docutils literal"><span class="pre">test_*.py</span></tt> and <tt class="docutils literal"><span class="pre">*_test.py</span></tt> files. Those files
are imported under their <a class="reference internal" href="#package-name">package name</a>.</p>
<p>The Module collector looks for test functions
and test classes and methods. Test functions and methods
are prefixed <tt class="docutils literal"><span class="pre">test</span></tt> by default. Test classes must
start with a capitalized <tt class="docutils literal"><span class="pre">Test</span></tt> prefix.</p>
</div>
<div class="section" id="test-items-are-collectors-as-well">
<span id="collector-api"></span><h3>1.8.1.2. test items are collectors as well<a class="headerlink" href="#test-items-are-collectors-as-well" title="Permalink to this headline"></a></h3>
<p>To make the reporting life simple for the session object
items offer a <tt class="docutils literal"><span class="pre">run()</span></tt> method as well. In fact the session
distinguishes &#8220;collectors&#8221; from &#8220;items&#8221; solely by interpreting
their return value. If it is a list, then we recurse into
it, otherwise we consider the &#8220;test&#8221; as passed.</p>
</div>
<div class="section" id="constructing-the-package-name-for-test-modules">
<span id="package-name"></span><h3>1.8.1.3. constructing the package name for test modules<a class="headerlink" href="#constructing-the-package-name-for-test-modules" title="Permalink to this headline"></a></h3>
<p>Test modules are imported under their fully qualified
name. Given a filesystem <tt class="docutils literal"><span class="pre">fspath</span></tt> it is constructed as follows:</p>
<ul class="simple">
<li>walk the directories up to the last one that contains
an <tt class="docutils literal"><span class="pre">__init__.py</span></tt> file.</li>
<li>perform <tt class="docutils literal"><span class="pre">sys.path.insert(0,</span> <span class="pre">basedir)</span></tt>.</li>
<li>import the root package as <tt class="docutils literal"><span class="pre">root</span></tt></li>
<li>determine the fully qualified name for <tt class="docutils literal"><span class="pre">fspath</span></tt> by either:<ul>
<li>calling <tt class="docutils literal"><span class="pre">root.__pkg__.getimportname(fspath)</span></tt> if the
<tt class="docutils literal"><span class="pre">__pkg__</span></tt> exists.` or</li>
<li>otherwise use the relative path of the module path to
the base dir and turn slashes into dots and strike
the trailing <tt class="docutils literal"><span class="pre">.py</span></tt>.</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section" id="customizing-the-testing-process">
<h2>1.8.2. Customizing the testing process<a class="headerlink" href="#customizing-the-testing-process" title="Permalink to this headline"></a></h2>
<div class="section" id="writing-conftest-py-files">
<h3>1.8.2.1. writing conftest.py files<a class="headerlink" href="#writing-conftest-py-files" title="Permalink to this headline"></a></h3>
<p>You may put conftest.py files containing project-specific
configuration in your project&#8217;s root directory, it&#8217;s usually
best to put it just into the same directory level as your
topmost <tt class="docutils literal"><span class="pre">__init__.py</span></tt>. In fact, <tt class="docutils literal"><span class="pre">py.test</span></tt> performs
an &#8220;upwards&#8221; search starting from the directory that you specify
to be tested and will lookup configuration values right-to-left.
You may have options that reside e.g. in your home directory
but note that project specific settings will be considered
first. There is a flag that helps you debugging your
conftest.py configurations:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span> <span class="o">--</span><span class="n">traceconfig</span>
</pre></div>
</div>
</div>
<div class="section" id="customizing-the-collecting-and-running-process">
<h3>1.8.2.2. customizing the collecting and running process<a class="headerlink" href="#customizing-the-collecting-and-running-process" title="Permalink to this headline"></a></h3>
<p>To introduce different test items you can create
one or more <tt class="docutils literal"><span class="pre">conftest.py</span></tt> files in your project.
When the collection process traverses directories
and modules the default collectors will produce
custom Collectors and Items if they are found
in a local <tt class="docutils literal"><span class="pre">conftest.py</span></tt> file.</p>
<div class="section" id="example-perform-additional-rest-checks">
<h4>1.8.2.2.1. example: perform additional ReST checks<a class="headerlink" href="#example-perform-additional-rest-checks" title="Permalink to this headline"></a></h4>
<p>With your custom collectors or items you can completely
derive from the standard way of collecting and running
tests in a localized manner. Let&#8217;s look at an example.
If you invoke <tt class="docutils literal"><span class="pre">py.test</span> <span class="pre">--collectonly</span> <span class="pre">py/documentation</span></tt>
then you get:</p>
<div class="highlight-python"><pre>&lt;DocDirectory 'documentation'&gt;
&lt;DocDirectory 'example'&gt;
&lt;DocDirectory 'pytest'&gt;
&lt;Module 'test_setup_flow_example.py' (test_setup_flow_example)&gt;
&lt;Class 'TestStateFullThing'&gt;
&lt;Instance '()'&gt;
&lt;Function 'test_42'&gt;
&lt;Function 'test_23'&gt;
&lt;ReSTChecker 'TODO.txt'&gt;
&lt;ReSTSyntaxTest 'TODO.txt'&gt;
&lt;LinkCheckerMaker 'checklinks'&gt;
&lt;ReSTChecker 'api.txt'&gt;
&lt;ReSTSyntaxTest 'api.txt'&gt;
&lt;LinkCheckerMaker 'checklinks'&gt;
&lt;CheckLink 'getting-started.html'&gt;
...</pre>
</div>
<p>In <tt class="docutils literal"><span class="pre">py/documentation/conftest.py</span></tt> you find the following
customization:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">DocDirectory</span><span class="p">(</span><span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">collect</span><span class="o">.</span><span class="n">Directory</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">results</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">DocDirectory</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fspath</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="s">&#39;*.txt&#39;</span><span class="p">,</span> <span class="n">sort</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span>
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">basename</span><span class="p">)</span>
<span class="k">return</span> <span class="n">results</span>
<span class="k">def</span> <span class="nf">join</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&#39;.txt&#39;</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">DocDirectory</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fspath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="nb">file</span><span class="o">=</span><span class="mf">1</span><span class="p">):</span>
<span class="k">return</span> <span class="n">ReSTChecker</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
<span class="n">Directory</span> <span class="o">=</span> <span class="n">DocDirectory</span>
</pre></div>
</div>
<p>The existence of the &#8216;Directory&#8217; name in the
<tt class="docutils literal"><span class="pre">pypy/documentation/conftest.py</span></tt> module makes the collection
process defer to our custom &#8220;DocDirectory&#8221; collector. We extend
the set of collected test items by <tt class="docutils literal"><span class="pre">ReSTChecker</span></tt> instances
which themselves create <tt class="docutils literal"><span class="pre">ReSTSyntaxTest</span></tt> and <tt class="docutils literal"><span class="pre">LinkCheckerMaker</span></tt>
items. All of this instances (need to) follow the <a class="reference internal" href="#collector-api">collector API</a>.</p>
</div>
</div>
<div class="section" id="customizing-the-reporting-of-test-failures">
<h3>1.8.2.3. Customizing the reporting of Test Failures<a class="headerlink" href="#customizing-the-reporting-of-test-failures" title="Permalink to this headline"></a></h3>
<p>XXX implement Item.repr_run and Item.repr_path for your test items</p>
</div>
<div class="section" id="writing-new-assertion-methods">
<h3>1.8.2.4. Writing new assertion methods<a class="headerlink" href="#writing-new-assertion-methods" title="Permalink to this headline"></a></h3>
<p>XXX __tracebackhide__, and use &#8220;print&#8221;</p>
</div>
<div class="section" id="customizing-the-collection-process-in-a-module">
<h3>1.8.2.5. Customizing the collection process in a module<a class="headerlink" href="#customizing-the-collection-process-in-a-module" title="Permalink to this headline"></a></h3>
<blockquote>
REPEATED WARNING: details of the collection and running process are
still subject to refactorings and thus details will change.
If you are customizing py.test at &#8220;Item&#8221; level then you
definitely want to be subscribed to the <a class="reference external" href="http://codespeak.net/mailman/listinfo/py-dev">py-dev mailing list</a>
to follow ongoing development.</blockquote>
<p>If you have a module where you want to take responsibility for
collecting your own test Items and possibly even for executing
a test then you can provide <a class="reference external" href="test-features.html#generative-tests">generative tests</a> that yield
callables and possibly arguments as a tuple. This is especially
useful for calling application test machinery with different
parameter sets but counting each of the calls as a separate
tests.</p>
<p>The other extension possibility is about
specifying a custom test <tt class="docutils literal"><span class="pre">Item</span></tt> class which
is responsible for setting up and executing an underlying
test. Or you can extend the collection process for a whole
directory tree by putting Items in a <tt class="docutils literal"><span class="pre">conftest.py</span></tt> configuration file.
The collection process dynamically consults the <em>chain of conftest.py</em>
modules to determine collectors and items at <tt class="docutils literal"><span class="pre">Directory</span></tt>, <tt class="docutils literal"><span class="pre">Module</span></tt>,
<tt class="docutils literal"><span class="pre">Class</span></tt>, <tt class="docutils literal"><span class="pre">Function</span></tt> or <tt class="docutils literal"><span class="pre">Generator</span></tt> level respectively.</p>
</div>
<div class="section" id="customizing-execution-of-functions">
<h3>1.8.2.6. Customizing execution of Functions<a class="headerlink" href="#customizing-execution-of-functions" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">py.test.collect.Function</span></tt> test items control execution
of a test function. <tt class="docutils literal"><span class="pre">function.run()</span></tt> will get called by the
session in order to actually run a test. The method is responsible
for performing proper setup/teardown (&#8220;Test Fixtures&#8221;) for a
Function test.</li>
<li><tt class="docutils literal"><span class="pre">Function.execute(target,</span> <span class="pre">*args)</span></tt> methods are invoked by
the default <tt class="docutils literal"><span class="pre">Function.run()</span></tt> to actually execute a python
function with the given (usually empty set of) arguments.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.8. Implementation and Customization of <tt class="docutils literal"><span class="pre">py.test</span></tt></a><ul>
<li><a class="reference external" href="#collecting-and-running-tests-implementation-remarks">1.8.1. Collecting and running tests / implementation remarks</a><ul>
<li><a class="reference external" href="#collectors-and-the-test-collection-process">1.8.1.1. Collectors and the test collection process</a></li>
<li><a class="reference external" href="#test-items-are-collectors-as-well">1.8.1.2. test items are collectors as well</a></li>
<li><a class="reference external" href="#constructing-the-package-name-for-test-modules">1.8.1.3. constructing the package name for test modules</a></li>
</ul>
</li>
<li><a class="reference external" href="#customizing-the-testing-process">1.8.2. Customizing the testing process</a><ul>
<li><a class="reference external" href="#writing-conftest-py-files">1.8.2.1. writing conftest.py files</a></li>
<li><a class="reference external" href="#customizing-the-collecting-and-running-process">1.8.2.2. customizing the collecting and running process</a><ul>
<li><a class="reference external" href="#example-perform-additional-rest-checks">1.8.2.2.1. example: perform additional ReST checks</a></li>
</ul>
</li>
<li><a class="reference external" href="#customizing-the-reporting-of-test-failures">1.8.2.3. Customizing the reporting of Test Failures</a></li>
<li><a class="reference external" href="#writing-new-assertion-methods">1.8.2.4. Writing new assertion methods</a></li>
<li><a class="reference external" href="#customizing-the-collection-process-in-a-module">1.8.2.5. Customizing the collection process in a module</a></li>
<li><a class="reference external" href="#customizing-execution-of-functions">1.8.2.6. Customizing execution of Functions</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-examples.html"
title="previous chapter">1.7. Working Examples</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="execnet.html"
title="next chapter">2. py.execnet</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/impl-test.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
>next</a> |</li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,229 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>py lib: Main tools and APIs &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="" />
<link rel="next" title="1. py.test" href="test.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test.html" title="1. py.test"
accesskey="N">next</a> |</li>
<li><a href="">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-lib-main-tools-and-apis">
<h1>py lib: Main tools and APIs<a class="headerlink" href="#py-lib-main-tools-and-apis" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="test.html">py.test</a> write and deploy unit- and functional tests to multiple machines.</p>
<p><a class="reference external" href="execnet.html">py.execnet</a> rapidly deploy local or remote processes from your program.</p>
<p><a class="reference external" href="path.html">py.path</a>: use path objects to transparently access local and svn filesystems.</p>
<p><a class="reference external" href="code.html">py.code</a>: generate python code and use advanced introspection/traceback support.</p>
</div>
<div class="section" id="minor-support-functionality">
<h1>Minor support functionality<a class="headerlink" href="#minor-support-functionality" title="Permalink to this headline"></a></h1>
<p><a class="reference external" href="bin.html">py lib scripts</a> to make python development easier.</p>
<p><a class="reference external" href="xml.html">py.xml</a> for generating in-memory xml/html object trees</p>
<p><a class="reference external" href="io.html">py.io</a>: Helper Classes for Capturing of Input/Output</p>
<p><a class="reference external" href="log.html">py.log</a>: an alpha document about the ad-hoc logging facilities</p>
<p><a class="reference external" href="misc.html">miscellaneous features</a> describes some small but nice py lib features.</p>
</div>
<div class="section" id="full-contents">
<h1>Full Contents<a class="headerlink" href="#full-contents" title="Permalink to this headline"></a></h1>
<ul>
<li class="toctree-l1"><a class="reference external" href="test.html">1. py.test</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-quickstart.html">1.1. Quickstart</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html">1.2. Features</a></li>
<li class="toctree-l2"><a class="reference external" href="test-plugins.html">1.3. Included plugins</a></li>
<li class="toctree-l2"><a class="reference external" href="test-ext.html">1.4. Writing plugins</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html">1.5. Distributed testing</a></li>
<li class="toctree-l2"><a class="reference external" href="test-config.html">1.6. Test configuration</a></li>
<li class="toctree-l2"><a class="reference external" href="test-examples.html">1.7. Working Examples</a></li>
<li class="toctree-l2"><a class="reference external" href="impl-test.html">1.8. Implementation and Customization of <tt class="docutils literal"><span class="pre">py.test</span></tt></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="execnet.html">2. py.execnet</a><ul>
<li class="toctree-l2"><a class="reference external" href="execnet.html#gateways-immediately-spawn-local-or-remote-process">2.1. Gateways: immediately spawn local or remote process</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#remote-exec-execute-source-code-remotely">2.2. remote_exec: execute source code remotely</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#channels-bidirectionally-exchange-data-between-hosts">2.3. Channels: bidirectionally exchange data between hosts</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#xspec-string-specification-for-gateway-type-and-configuration">2.4. XSpec: string specification for gateway type and configuration</a></li>
<li class="toctree-l2"><a class="reference external" href="execnet.html#examples-of-py-execnet-usage">2.5. Examples of py.execnet usage</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="path.html">3. py.path</a><ul>
<li class="toctree-l2"><a class="reference external" href="path.html#path-implementations-provided-by-py-path">3.1. Path implementations provided by <tt class="docutils literal"><span class="pre">py.path</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#common-vs-specific-api">3.2. Common vs. specific API</a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#known-problems-limitations">3.3. Known problems / limitations</a></li>
<li class="toctree-l2"><a class="reference external" href="path.html#future-plans">3.4. Future plans</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="code.html">4. py.code</a><ul>
<li class="toctree-l2"><a class="reference external" href="code.html#contents-of-the-library">4.1. Contents of the library</a></li>
<li class="toctree-l2"><a class="reference external" href="code.html#the-wrappers">4.2. The wrappers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="bin.html">5. <tt class="docutils literal"><span class="pre">py/bin/</span></tt> scripts</a><ul>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-test">5.1. <tt class="docutils literal"><span class="pre">py.test</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-cleanup">5.2. <tt class="docutils literal"><span class="pre">py.cleanup</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-countloc">5.3. <tt class="docutils literal"><span class="pre">py.countloc</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-lookup">5.4. <tt class="docutils literal"><span class="pre">py.lookup</span></tt></a></li>
<li class="toctree-l2"><a class="reference external" href="bin.html#py-rest">5.5. <tt class="docutils literal"><span class="pre">py.rest</span></tt></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="xml.html">6. py.xml: Lightweight and flexible xml/html generation</a><ul>
<li class="toctree-l2"><a class="reference external" href="xml.html#motivation">6.1. Motivation</a></li>
<li class="toctree-l2"><a class="reference external" href="xml.html#a-pythonic-object-model-please">6.2. a pythonic object model , please</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="io.html">7. py.io</a><ul>
<li class="toctree-l2"><a class="reference external" href="io.html#io-capturing-examples">7.1. IO Capturing examples</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="log.html">8. py.log documentation and musings</a><ul>
<li class="toctree-l2"><a class="reference external" href="log.html#foreword">8.1. Foreword</a></li>
<li class="toctree-l2"><a class="reference external" href="log.html#logging-organisation">8.2. Logging organisation</a></li>
<li class="toctree-l2"><a class="reference external" href="log.html#using-the-py-log-library">8.3. Using the py.log library</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="misc.html">9. Miscellaneous features of the py lib</a><ul>
<li class="toctree-l2"><a class="reference external" href="misc.html#mapping-the-standard-python-library-into-py">9.1. Mapping the standard python library into py</a></li>
<li class="toctree-l2"><a class="reference external" href="misc.html#support-for-interaction-with-system-utilities-binaries">9.2. Support for interaction with system utilities/binaries</a></li>
<li class="toctree-l2"><a class="reference external" href="misc.html#cross-python-version-compatibility-helpers">9.3. Cross-Python Version compatibility helpers</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="why_py.html">10. Why, who, what and how do you do <em>the py lib</em>?</a><ul>
<li class="toctree-l2"><a class="reference external" href="why_py.html#why-did-we-start-the-py-lib">10.1. Why did we start the py lib?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#what-is-the-py-libs-current-focus">10.2. What is the py libs current focus?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#how-does-py-development-work">10.3. How does py development work?</a></li>
<li class="toctree-l2"><a class="reference external" href="why_py.html#who-is-we">10.4. Who is &#8220;we&#8221;?</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="future.html">11. Visions and ideas for further development of the py lib</a><ul>
<li class="toctree-l2"><a class="reference external" href="future.html#distribute-tests-ad-hoc-across-multiple-platforms">11.1. Distribute tests ad-hoc across multiple platforms</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#make-apigen-useful-for-more-projects">11.2. Make APIGEN useful for more projects</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#consider-apigen-and-pdb-integration">11.3. Consider APIGEN and pdb integration</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#distribute-channels-programs-across-networks">11.4. Distribute channels/programs across networks</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#benchmarking-and-persistent-storage">11.5. Benchmarking and persistent storage</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#refactor-path-implementations-to-use-a-filesystem-abstraction">11.6. Refactor path implementations to use a Filesystem Abstraction</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#integrate-interactive-completion">11.7. Integrate interactive completion</a></li>
<li class="toctree-l2"><a class="reference external" href="future.html#consider-more-features">11.8. Consider more features</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="coding-style.html">12. Coding Style for the Py lib and friendly applications</a><ul>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#honour-pep-8-style-guide-for-python-code">12.1. Honour PEP 8: Style Guide for Python Code</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#documentation-and-testing">12.2. Documentation and Testing</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#naming">12.3. naming</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#committing">12.4. committing</a></li>
<li class="toctree-l2"><a class="reference external" href="coding-style.html#miscellaneous">12.5. Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="links.html">13. Links</a></li>
<li class="toctree-l1"><a class="reference external" href="contact.html">14. Contact and communication</a></li>
<li class="toctree-l1"><a class="reference external" href="download.html">15. Downloading</a><ul>
<li class="toctree-l2"><a class="reference external" href="download.html#easy-install-py">15.1. &#8220;easy_install py&#8221;</a></li>
<li class="toctree-l2"><a class="reference external" href="download.html#installing-on-debian-or-fedora">15.2. Installing on Debian or Fedora</a></li>
<li class="toctree-l2"><a class="reference external" href="download.html#downloading-a-tar-zip-archive-and-installing-that">15.3. Downloading a tar/zip archive and installing that</a></li>
<li class="toctree-l2"><a class="reference external" href="download.html#installing-from-subversion-develop-mode">15.4. Installing from subversion / develop mode</a></li>
<li class="toctree-l2"><a class="reference external" href="download.html#working-with-multiple-py-lib-versions-svn-externals">15.5. Working with multiple py lib versions / svn externals</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="releases.html">16. Release notes</a><ul>
<li class="toctree-l2"><a class="reference external" href="release-1.0.0.html">16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more</a></li>
<li class="toctree-l2"><a class="reference external" href="release-0.9.2.html">16.2. py lib 0.9.2: bugfix release</a></li>
<li class="toctree-l2"><a class="reference external" href="release-0.9.0.html">16.3. py lib 1.0.0: XXX</a></li>
</ul>
</li>
</ul>
<ul class="simple">
<li><a class="reference external" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference external" href="modindex.html"><em>Module Index</em></a></li>
<li><a class="reference external" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">py lib: Main tools and APIs</a></li>
<li><a class="reference external" href="#minor-support-functionality">Minor support functionality</a></li>
<li><a class="reference external" href="#full-contents">Full Contents</a><ul>
</ul>
</li>
</ul>
<h4>Next topic</h4>
<p class="topless"><a href="test.html"
title="next chapter">1. py.test</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test.html" title="1. py.test"
>next</a> |</li>
<li><a href="">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,156 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>7. py.io &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="8. 1   py.log documentation and musings" href="log.html" />
<link rel="prev" title="6. py.xml: Lightweight and flexible xml/html generation" href="xml.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="log.html" title="8. 1   py.log documentation and musings"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="xml.html" title="6. py.xml: Lightweight and flexible xml/html generation"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-io">
<h1>7. py.io<a class="headerlink" href="#py-io" title="Permalink to this headline"></a></h1>
<p>The &#8216;py&#8217; lib provides helper classes for capturing IO during
execution of a program.</p>
<div class="section" id="io-capturing-examples">
<h2>7.1. IO Capturing examples<a class="headerlink" href="#io-capturing-examples" title="Permalink to this headline"></a></h2>
<div class="section" id="py-io-stdcapture">
<h3>7.1.1. <tt class="docutils literal"><span class="pre">py.io.StdCapture</span></tt><a class="headerlink" href="#py-io-stdcapture" title="Permalink to this headline"></a></h3>
<p>Basic Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">capture</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">io</span><span class="o">.</span><span class="n">StdCapture</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="s">&quot;hello&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">out</span><span class="p">,</span><span class="n">err</span> <span class="o">=</span> <span class="n">capture</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">out</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;hello&quot;</span>
<span class="go">True</span>
</pre></div>
</div>
<p>For calling functions you may use a shortcut:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">f</span><span class="p">():</span> <span class="k">print</span> <span class="s">&quot;hello&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">res</span><span class="p">,</span> <span class="n">out</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">io</span><span class="o">.</span><span class="n">StdCapture</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">out</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s">&quot;hello&quot;</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="py-io-stdcapturefd">
<h3>7.1.2. <tt class="docutils literal"><span class="pre">py.io.StdCaptureFD</span></tt><a class="headerlink" href="#py-io-stdcapturefd" title="Permalink to this headline"></a></h3>
<p>If you also want to capture writes to the stdout/stderr
filedescriptors you may invoke:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">capture</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">io</span><span class="o">.</span><span class="n">StdCaptureFD</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;world&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">out</span><span class="p">,</span><span class="n">err</span> <span class="o">=</span> <span class="n">capture</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">err</span>
<span class="go">&#39;world&#39;</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">7. py.io</a><ul>
<li><a class="reference external" href="#io-capturing-examples">7.1. IO Capturing examples</a><ul>
<li><a class="reference external" href="#py-io-stdcapture">7.1.1. <tt class="docutils literal"><span class="pre">py.io.StdCapture</span></tt></a></li>
<li><a class="reference external" href="#py-io-stdcapturefd">7.1.2. <tt class="docutils literal"><span class="pre">py.io.StdCaptureFD</span></tt></a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="xml.html"
title="previous chapter">6. py.xml: Lightweight and flexible xml/html generation</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="log.html"
title="next chapter">8. 1&nbsp;&nbsp;&nbsp;<strong class="code">py.log</strong> documentation and musings</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/io.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="log.html" title="8. 1   py.log documentation and musings"
>next</a> |</li>
<li class="right" >
<a href="xml.html" title="6. py.xml: Lightweight and flexible xml/html generation"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,120 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>13. Links &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="14. Contact and communication" href="contact.html" />
<link rel="prev" title="12. Coding Style for the Py lib and friendly applications" href="coding-style.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="contact.html" title="14. Contact and communication"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="coding-style.html" title="12. Coding Style for the Py lib and friendly applications"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="links">
<h1>13. Links<a class="headerlink" href="#links" title="Permalink to this headline"></a></h1>
<p>Some links to ongoing discussions and comments about pylib and technics/concepts pylib uses.</p>
<ul class="simple">
<li><a class="reference external" href="http://blog.ianbicking.org/site-packages-considered-harmful.html">Discussion</a>
about site-packages. That&#8217;s why pylib autopath and py.__.misc.dynpkg are a good idea ;-)</li>
<li><a class="reference external" href="http://pyinotify.sourceforge.net/">Pyinotify</a> uses code from pypy autopath functions.</li>
<li><a class="reference external" href="http://pythonpaste.org/testing-applications.html#the-test-environment">Testing (WSGI) Applications with Paste</a> and py.test. &#8220;This has been written with py.test in mind.&#8221; Paste uses py.test.</li>
<li><a class="reference external" href="http://agiletesting.blogspot.com/">Agile Testing</a> by Grig Gheorghiu<ul>
<li><a class="reference external" href="http://agiletesting.blogspot.com/2005/07/slides-from-py-library-overview.html">Slides from &#8216;py library overview&#8217; presentation at SoCal Piggies meeting</a></li>
<li><a class="reference external" href="http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-3-pytest-tool.html">Python unit testing part 3: the py.test tool and library</a></li>
<li><a class="reference external" href="http://agiletesting.blogspot.com/2005/07/py-lib-gems-greenlets-and-pyxml.html">greenlets and py.xml</a></li>
<li><a class="reference external" href="http://agiletesting.blogspot.com/2005/06/keyword-based-logging-with-py-library.html">Keyword-based logging with the py library</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="coding-style.html"
title="previous chapter">12. Coding Style for the Py lib and friendly applications</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="contact.html"
title="next chapter">14. Contact and communication</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/links.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="contact.html" title="14. Contact and communication"
>next</a> |</li>
<li class="right" >
<a href="coding-style.html" title="12. Coding Style for the Py lib and friendly applications"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,298 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>8. py.log documentation and musings &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="9. 1   Miscellaneous features of the py lib" href="misc.html" />
<link rel="prev" title="7. py.io" href="io.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="misc.html" title="9. 1   Miscellaneous features of the py lib"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="io.html" title="7. py.io"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-log-documentation-and-musings">
<h1>8. py.log documentation and musings<a class="headerlink" href="#py-log-documentation-and-musings" title="Permalink to this headline"></a></h1>
<div class="section" id="foreword">
<h2>8.1. Foreword<a class="headerlink" href="#foreword" title="Permalink to this headline"></a></h2>
<p>This document is an attempt to briefly state the actual specification of the
<tt class="code docutils literal"><span class="pre">py.log</span></tt> module. It was written by Francois Pinard and also contains
some ideas for enhancing the py.log facilities.</p>
<p>NOTE that <tt class="code docutils literal"><span class="pre">py.log</span></tt> is subject to refactorings, it may change with
the next release.</p>
<p>This document is meant to trigger or facilitate discussions. It shamelessly
steals from the <a class="reference external" href="http://agiletesting.blogspot.com/2005/06/keyword-based-logging-with-py-library.html">Agile Testing</a> comments, and from other sources as well,
without really trying to sort them out.</p>
</div>
<div class="section" id="logging-organisation">
<h2>8.2. Logging organisation<a class="headerlink" href="#logging-organisation" title="Permalink to this headline"></a></h2>
<p>The <tt class="code docutils literal"><span class="pre">py.log</span></tt> module aims a niche comparable to the one of the
<a class="reference external" href="http://www.python.org/doc/2.4.2/lib/module-logging.html">logging module</a> found within the standard Python distributions, yet
with much simpler paradigms for configuration and usage.</p>
<p>Holger Krekel, the main <tt class="code docutils literal"><span class="pre">py</span></tt> library developer, introduced
the idea of keyword-based logging and the idea of logging <em>producers</em> and
<em>consumers</em>. A log producer is an object used by the application code
to send messages to various log consumers. When you create a log
producer, you define a set of keywords that are then used to both route
the logging messages to consumers, and to prefix those messages.</p>
<p>In fact, each log producer has a few keywords associated with it for
identification purposes. These keywords form a tuple of strings, and
may be used to later retrieve a particular log producer.</p>
<p>A log producer may (or may not) be associated with a log consumer, meant
to handle log messages in particular ways. The log consumers can be
<tt class="docutils literal"><span class="pre">STDOUT</span></tt>, <tt class="docutils literal"><span class="pre">STDERR</span></tt>, log files, syslog, the Windows Event Log, user
defined functions, etc. (Yet, logging to syslog or to the Windows Event
Log is only future plans for now). A log producer has never more than
one consumer at a given time, but it is possible to dynamically switch
a producer to use another consumer. On the other hand, a single log
consumer may be associated with many producers.</p>
<p>Note that creating and associating a producer and a consumer is done
automatically when not otherwise overriden, so using <tt class="code docutils literal"><span class="pre">py</span></tt> logging
is quite comfortable even in the smallest programs. More typically,
the application programmer will likely design a hierarchy of producers,
and will select keywords appropriately for marking the hierarchy tree.
If a node of the hierarchical tree of producers has to be divided in
sub-trees, all producers in the sub-trees share, as a common prefix, the
keywords of the node being divided. In other words, we go further down
in the hierarchy of producers merely by adding keywords.</p>
</div>
<div class="section" id="using-the-py-log-library">
<h2>8.3. Using the py.log library<a class="headerlink" href="#using-the-py-log-library" title="Permalink to this headline"></a></h2>
<p>To use the <tt class="code docutils literal"><span class="pre">py.log</span></tt> library, the user must import it into a Python
application, create at least one log producer and one log consumer, have
producers and consumers associated, and finally call the log producers
as needed, giving them log messages.</p>
<div class="section" id="importing">
<h3>8.3.1. Importing<a class="headerlink" href="#importing" title="Permalink to this headline"></a></h3>
<p>Once the <tt class="code docutils literal"><span class="pre">py</span></tt> library is installed on your system, a mere:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">py</span>
</pre></div>
</div>
<p>holds enough magic for lazily importing the various facilities of the
<tt class="code docutils literal"><span class="pre">py</span></tt> library when they are first needed. This is really how
<tt class="code docutils literal"><span class="pre">py.log</span></tt> is made available to the application. For example, after
the above <tt class="docutils literal"><span class="pre">import</span> <span class="pre">py</span></tt>, one may directly write <tt class="docutils literal"><span class="pre">py.log.Producer(...)</span></tt>
and everything should work fine, the user does not have to worry about
specifically importing more modules.</p>
</div>
<div class="section" id="creating-a-producer">
<h3>8.3.2. Creating a producer<a class="headerlink" href="#creating-a-producer" title="Permalink to this headline"></a></h3>
<p>There are three ways for creating a log producer instance:</p>
<blockquote>
<ul class="simple">
<li>As soon as <tt class="docutils literal"><span class="pre">py.log</span></tt> is first evaluated within an application
program, a default log producer is created, and made available under
the name <tt class="docutils literal"><span class="pre">py.log.default</span></tt>. The keyword <tt class="docutils literal"><span class="pre">default</span></tt> is associated
with that producer.</li>
<li>The <tt class="docutils literal"><span class="pre">py.log.Producer()</span></tt> constructor may be explicitly called
for creating a new instance of a log producer. That constructor
accepts, as an argument, the keywords that should be associated with
that producer. Keywords may be given either as a tuple of keyword
strings, or as a single space-separated string of keywords.</li>
<li>Whenever an attribute is <em>taken</em> out of a log producer instance,
for the first time that attribute is taken, a new log producer is
created. The keywords associated with that new producer are those
of the initial producer instance, to which is appended the name of
the attribute being taken.</li>
</ul>
</blockquote>
<p>The last point is especially useful, as it allows using log producers
without further declarations, merely creating them <em>on-the-fly</em>.</p>
</div>
<div class="section" id="creating-a-consumer">
<h3>8.3.3. Creating a consumer<a class="headerlink" href="#creating-a-consumer" title="Permalink to this headline"></a></h3>
<p>There are many ways for creating or denoting a log consumer:</p>
<blockquote>
<ul>
<li><p class="first">A default consumer exists within the <tt class="docutils literal"><span class="pre">py.log</span></tt> facilities, which
has the effect of writing log messages on the Python standard output
stream. That consumer is associated at the very top of the producer
hierarchy, and as such, is called whenever no other consumer is
found.</p>
</li>
<li><p class="first">The notation <tt class="docutils literal"><span class="pre">py.log.STDOUT</span></tt> accesses a log consumer which writes
log messages on the Python standard output stream.</p>
</li>
<li><p class="first">The notation <tt class="docutils literal"><span class="pre">py.log.STDERR</span></tt> accesses a log consumer which writes
log messages on the Python standard error stream.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">py.log.File()</span></tt> constructor accepts, as argument, either a file
already opened in write mode or any similar file-like object, and
creates a log consumer able to write log messages onto that file.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">py.log.Path()</span></tt> constructor accepts a file name for its first
argument, and creates a log consumer able to write log messages into
that file. The constructor call accepts a few keyword parameters:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">append</span></tt>, which is <tt class="xref docutils literal"><span class="pre">False</span></tt> by default, may be used for
opening the file in append mode instead of write mode.</li>
<li><tt class="docutils literal"><span class="pre">delayed_create</span></tt>, which is <tt class="xref docutils literal"><span class="pre">False</span></tt> by default, maybe be used
for opening the file at the latest possible time. Consequently,
the file will not be created if it did not exist, and no actual
log message gets written to it.</li>
<li><tt class="docutils literal"><span class="pre">buffering</span></tt>, which is 1 by default, is used when opening the
file. Buffering can be turned off by specifying a 0 value. The
buffer size may also be selected through this argument.</li>
</ul>
</blockquote>
</li>
<li><p class="first">Any user defined function may be used for a log consumer. Such a
function should accept a single argument, which is the message to
write, and do whatever is deemed appropriate by the programmer.
When the need arises, this may be an especially useful and flexible
feature.</p>
</li>
<li><p class="first">The special value <tt class="xref docutils literal"><span class="pre">None</span></tt> means no consumer at all. This acts just
like if there was a consumer which would silently discard all log
messages sent to it.</p>
</li>
</ul>
</blockquote>
</div>
<div class="section" id="associating-producers-and-consumers">
<h3>8.3.4. Associating producers and consumers<a class="headerlink" href="#associating-producers-and-consumers" title="Permalink to this headline"></a></h3>
<p>Each log producer may have at most one log consumer associated with
it. A log producer gets associated with a log consumer through a
<tt class="docutils literal"><span class="pre">py.log.set_consumer()</span></tt> call. That function accepts two arguments,
the first identifying a producer (a tuple of keyword strings or a single
space-separated string of keywords), the second specifying the precise
consumer to use for that producer. Until this function is called for a
producer, that producer does not have any explicit consumer associated
with it.</p>
<p>Now, the hierarchy of log producers establishes which consumer gets used
whenever a producer has no explicit consumer. When a log producer
has no consumer explicitly associated with it, it dynamically and
recursively inherits the consumer of its parent node, that is, that node
being a bit closer to the root of the hierarchy. In other words, the
rightmost keywords of that producer are dropped until another producer
is found which has an explicit consumer. A nice side-effect is that,
by explicitly associating a consumer with a producer, all consumer-less
producers which appear under that producer, in the hierarchy tree,
automatically <em>inherits</em> that consumer.</p>
</div>
<div class="section" id="writing-log-messages">
<h3>8.3.5. Writing log messages<a class="headerlink" href="#writing-log-messages" title="Permalink to this headline"></a></h3>
<p>All log producer instances are also functions, and this is by calling
them that log messages are generated. Each call to a producer object
produces the text for one log entry, which in turn, is sent to the log
consumer for that producer.</p>
<p>The log entry displays, after a prefix identifying the log producer
being used, all arguments given in the call, converted to strings and
space-separated. (This is meant by design to be fairly similar to what
the <tt class="docutils literal"><span class="pre">print</span></tt> statement does in Python). The prefix itself is made up
of a colon-separated list of keywords associated with the producer, the
whole being set within square brackets.</p>
<p>Note that the consumer is responsible for adding the newline at the end
of the log entry. That final newline is not part of the text for the
log entry.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">8. py.log documentation and musings</a><ul>
<li><a class="reference external" href="#foreword">8.1. Foreword</a></li>
<li><a class="reference external" href="#logging-organisation">8.2. Logging organisation</a></li>
<li><a class="reference external" href="#using-the-py-log-library">8.3. Using the py.log library</a><ul>
<li><a class="reference external" href="#importing">8.3.1. Importing</a></li>
<li><a class="reference external" href="#creating-a-producer">8.3.2. Creating a producer</a></li>
<li><a class="reference external" href="#creating-a-consumer">8.3.3. Creating a consumer</a></li>
<li><a class="reference external" href="#associating-producers-and-consumers">8.3.4. Associating producers and consumers</a></li>
<li><a class="reference external" href="#writing-log-messages">8.3.5. Writing log messages</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="io.html"
title="previous chapter">7. py.io</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="misc.html"
title="next chapter">9. 1&nbsp;&nbsp;&nbsp;Miscellaneous features of the py lib</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/log.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="misc.html" title="9. 1   Miscellaneous features of the py lib"
>next</a> |</li>
<li class="right" >
<a href="io.html" title="7. py.io"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,321 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>9. Miscellaneous features of the py lib &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="10. 1   Why, who, what and how do you do the py lib?" href="why_py.html" />
<link rel="prev" title="8. py.log documentation and musings" href="log.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="why_py.html" title="10. 1   Why, who, what and how do you do the py lib?"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="log.html" title="8. py.log documentation and musings"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="miscellaneous-features-of-the-py-lib">
<h1>9. Miscellaneous features of the py lib<a class="headerlink" href="#miscellaneous-features-of-the-py-lib" title="Permalink to this headline"></a></h1>
<div class="section" id="mapping-the-standard-python-library-into-py">
<h2>9.1. Mapping the standard python library into py<a class="headerlink" href="#mapping-the-standard-python-library-into-py" title="Permalink to this headline"></a></h2>
<blockquote>
Warning: This feature is very young and thus experimental.
Be prepared to adapt your code later if you use it.</blockquote>
<p>After you have worked with the py lib a bit, you might enjoy
the lazy importing, i.e. you only have to do <tt class="docutils literal"><span class="pre">import</span> <span class="pre">py</span></tt> and
work your way to your desired object. Using the full path
also ensures that there remains a focus on getting short paths
to objects.</p>
<div class="section" id="the-py-std-hook">
<h3>9.1.1. The <tt class="docutils literal"><span class="pre">py.std</span></tt> hook<a class="headerlink" href="#the-py-std-hook" title="Permalink to this headline"></a></h3>
<p>Of course, no matter what, everybody will continue to use the
python standard library because it is a very usable code base.
However, to properly support lazyness the py lib offers a way
to get to many standard modules without requiring &#8220;import&#8221;
statements. For example, to get to the print-exception
functionality of the standard library you can write:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">std</span><span class="o">.</span><span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
</pre></div>
</div>
<p>without having to do anything else than the usual <tt class="docutils literal"><span class="pre">import</span> <span class="pre">py</span></tt>
at the beginning. Note that not having imports for the
<cite>python standard library</cite> obviously gets rid of the <em>unused
import</em> problem. Modules only get imported when you actually
need them.</p>
<p>Moreover, this approach resolves some of the issues stated in
<a class="reference external" href="http://www.python.org/peps/pep-0328.html">the relative/absolute import PEP-328</a>, as with the above
approach you never have ambiguity problems. The above
traceback-usage is an absolute path that will not be
accidentally get confused with local names. (Well, never put
a file <tt class="docutils literal"><span class="pre">py.py</span></tt> in an importable path, btw, mind you :-)</p>
</div>
<div class="section" id="automagically-accessing-sub-packages-doesn-t-work-yet">
<h3>9.1.2. Automagically accessing sub packages doesn&#8217;t work (yet?)<a class="headerlink" href="#automagically-accessing-sub-packages-doesn-t-work-yet" title="Permalink to this headline"></a></h3>
<p>If you use the <tt class="docutils literal"><span class="pre">py.std</span></tt> hook you currently cannot magically
import nested packages which otherwise need explicit imports of
their sub-packages. For example, the suversion bindings
require you to do something like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">svn.client</span>
</pre></div>
</div>
<p>If you just do the naive thing with the py lib, i.e. write
<tt class="docutils literal"><span class="pre">py.std.svn.client</span></tt> it will not work unless you previously
imported it already. The py lib currently doesn&#8217;t try to
magically make this work. The <tt class="docutils literal"><span class="pre">py.std</span></tt> hook really is
intended for Python standard modules which very seldomly (if
at all) provide such nested packages.</p>
<p><strong>Note that you may never rely</strong> on module identity, i.e.
that <tt class="docutils literal"><span class="pre">X</span> <span class="pre">is</span> <span class="pre">py.std.X</span></tt> for any <tt class="docutils literal"><span class="pre">X</span></tt>. This is to allow
us later to lazyly import nested packages. Yes, lazyness
is hard to resist :-)</p>
</div>
<div class="section" id="note-you-get-an-attributeerror-not-an-importerror">
<h3>9.1.3. Note: you get an AttributeError, not an ImportError<a class="headerlink" href="#note-you-get-an-attributeerror-not-an-importerror" title="Permalink to this headline"></a></h3>
<p>If you say <tt class="docutils literal"><span class="pre">py.std.XYZ</span></tt> and importing <tt class="docutils literal"><span class="pre">XYZ</span></tt> produces an
<tt class="docutils literal"><span class="pre">ImportError</span></tt> , it will actually show up as an
<tt class="docutils literal"><span class="pre">AttributeError</span></tt>. It is deemed more important to adhere to
the standard <tt class="docutils literal"><span class="pre">__getattr__</span></tt> protocol than to let the
<tt class="docutils literal"><span class="pre">ImportError</span></tt> pass through. For example, you might want to
do:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nb">getattr</span><span class="p">(</span><span class="n">py</span><span class="o">.</span><span class="n">std</span><span class="o">.</span><span class="n">cStringIO</span><span class="p">,</span> <span class="s">&#39;StringIO&#39;</span><span class="p">,</span> <span class="n">py</span><span class="o">.</span><span class="n">std</span><span class="o">.</span><span class="n">StringIO</span><span class="o">.</span><span class="n">StringIO</span><span class="p">)</span>
</pre></div>
</div>
<p>and you would expect that it works. It does work although it will
take away some lazyness because <tt class="docutils literal"><span class="pre">py.std.StringIO.StringIO</span></tt> will
be imported in any case.</p>
</div>
</div>
<div class="section" id="support-for-interaction-with-system-utilities-binaries">
<h2>9.2. Support for interaction with system utilities/binaries<a class="headerlink" href="#support-for-interaction-with-system-utilities-binaries" title="Permalink to this headline"></a></h2>
<p>sources:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">py/process/</span></tt></li>
<li><tt class="docutils literal"><span class="pre">py/path/local/</span></tt></li>
</ul>
</blockquote>
<p>Currently, the py lib offers two ways to interact with
system executables. <tt class="docutils literal"><span class="pre">py.process.cmdexec()</span></tt> invokes
the shell in order to execute a string. The other
one, <tt class="docutils literal"><span class="pre">py.path.local</span></tt>&#8216;s &#8216;sysexec()&#8217; method lets you
directly execute a binary.</p>
<p>Both approaches will raise an exception in case of a return-
code other than 0 and otherwise return the stdout-output
of the child process.</p>
<div class="section" id="the-shell-based-approach">
<h3>9.2.1. The shell based approach<a class="headerlink" href="#the-shell-based-approach" title="Permalink to this headline"></a></h3>
<p>You can execute a command via your system shell
by doing something like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">out</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">process</span><span class="o">.</span><span class="n">cmdexec</span><span class="p">(</span><span class="s">&#39;ls -v&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>However, the <tt class="docutils literal"><span class="pre">cmdexec</span></tt> approach has a few shortcomings:</p>
<ul class="simple">
<li>it relies on the underlying system shell</li>
<li>it neccessitates shell-escaping for expressing arguments</li>
<li>it does not easily allow to &#8220;fix&#8221; the binary you want to run.</li>
<li>it only allows to execute executables from the local
filesystem</li>
</ul>
</div>
<div class="section" id="local-paths-have-sysexec">
<span id="sysexec"></span><h3>9.2.2. local paths have <tt class="docutils literal"><span class="pre">sysexec</span></tt><a class="headerlink" href="#local-paths-have-sysexec" title="Permalink to this headline"></a></h3>
<p>The py lib currently offers a stripped down functionality of what
the new <a class="reference external" href="http://www.python.org/peps/pep-0324.html">PEP-324 subprocess module</a> offers. The main functionality
of synchronously executing a system executable has a straightforward API:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">binsvn</span><span class="o">.</span><span class="n">sysexec</span><span class="p">(</span><span class="s">&#39;ls&#39;</span><span class="p">,</span> <span class="s">&#39;http://codespeak.net/svn&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>where <tt class="docutils literal"><span class="pre">binsvn</span></tt> is a path that points to the <tt class="docutils literal"><span class="pre">svn</span></tt> commandline
binary. Note that this function would not offer any shell-escaping
so you really have to pass in separated arguments. This idea
fits nicely into <a class="reference external" href="future.html#general-path">a more general view on path objects</a>.</p>
<p>For a first go, we are just reusing the existing <a class="reference external" href="http://www.lysator.liu.se/~astrand/popen5/">subprocess
implementation</a> but don&#8217;t expose any of its API apart
from the above <tt class="docutils literal"><span class="pre">sysexec()</span></tt> method.</p>
<p>Note, however, that currently the support for the <tt class="docutils literal"><span class="pre">sysexec</span></tt> interface on
win32 is not thoroughly tested. If you run into problems with it, we are
interested to hear about them. If you are running a Python older than 2.4 you
will have to install the <a class="reference external" href="http://pywin32.sourceforge.net/">pywin32 package</a>.</p>
</div>
<div class="section" id="finding-an-executable-local-path">
<h3>9.2.3. finding an executable local path<a class="headerlink" href="#finding-an-executable-local-path" title="Permalink to this headline"></a></h3>
<p>Finding an executable is quite different on multiple platforms.
Currently, the <tt class="docutils literal"><span class="pre">PATH</span></tt> environment variable based search on
unix platforms is supported:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="o">.</span><span class="n">sysfind</span><span class="p">(</span><span class="s">&#39;svn&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>which returns the first path whose <tt class="docutils literal"><span class="pre">basename</span></tt> matches <tt class="docutils literal"><span class="pre">svn</span></tt>.
In principle, <cite>sysfind</cite> deploys platform specific algorithms
to perform the search. On Windows, for example, it may look
at the registry (XXX).</p>
<p>To make the story complete, we allow to pass in a second <tt class="docutils literal"><span class="pre">checker</span></tt>
argument that is called for each found executable. For example, if
you have multiple binaries available you may want to select the
right version:</p>
<div class="highlight-python"><pre>def mysvn(p):
""" check that the given svn binary has version 1.1. """
line = p.execute('--version'').readlines()[0]
if line.find('version 1.1'):
return p
binsvn = py.path.local.sysfind('svn', checker=mysvn)</pre>
</div>
</div>
</div>
<div class="section" id="cross-python-version-compatibility-helpers">
<h2>9.3. Cross-Python Version compatibility helpers<a class="headerlink" href="#cross-python-version-compatibility-helpers" title="Permalink to this headline"></a></h2>
<p>sources:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">py/compat/</span></tt></li>
<li><tt class="docutils literal"><span class="pre">py/builtin/</span></tt></li>
</ul>
</blockquote>
<p>The compat and builtin namespaces help to write code using newer python features on older python interpreters.</p>
<div class="section" id="py-compat">
<h3>9.3.1. <tt class="docutils literal"><span class="pre">py.compat</span></tt><a class="headerlink" href="#py-compat" title="Permalink to this headline"></a></h3>
<p><tt class="docutils literal"><span class="pre">py.compat</span></tt> provides fixed versions (currently taken from Python 2.4.4) of
a few selected modules to be able to use them across python versions. Currently these are:</p>
<blockquote>
<ul class="simple">
<li>doctest</li>
<li>optparse</li>
<li>subprocess</li>
<li>textwrap</li>
</ul>
</blockquote>
<p>Note that for example <tt class="docutils literal"><span class="pre">import</span> <span class="pre">doctest</span></tt> and <tt class="docutils literal"><span class="pre">from</span> <span class="pre">py.compat</span> <span class="pre">import</span> <span class="pre">doctest</span></tt> result
into two different module objects no matter what Python version you are using.
So you should only use exactly one of these to avoid confusion in your program.</p>
</div>
<div class="section" id="py-builtin">
<h3>9.3.2. <tt class="docutils literal"><span class="pre">py.builtin</span></tt><a class="headerlink" href="#py-builtin" title="Permalink to this headline"></a></h3>
<p><tt class="docutils literal"><span class="pre">py.builtin</span></tt> provides builtin functions/types that were added in later Python
versions. If the used Python version used does not provide these builtins the
py lib provides some reimplementations. These currently are:</p>
<blockquote>
<ul class="simple">
<li>enumerate</li>
<li>reversed</li>
<li>sorted</li>
<li>BaseException</li>
<li>set and frozenset (using either the builtin, if available, or the sets
module)</li>
</ul>
</blockquote>
<p><tt class="docutils literal"><span class="pre">py.builtin.BaseException</span></tt> is just <tt class="docutils literal"><span class="pre">Exception</span></tt> before Python 2.5.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">9. Miscellaneous features of the py lib</a><ul>
<li><a class="reference external" href="#mapping-the-standard-python-library-into-py">9.1. Mapping the standard python library into py</a><ul>
<li><a class="reference external" href="#the-py-std-hook">9.1.1. The <tt class="docutils literal"><span class="pre">py.std</span></tt> hook</a></li>
<li><a class="reference external" href="#automagically-accessing-sub-packages-doesn-t-work-yet">9.1.2. Automagically accessing sub packages doesn&#8217;t work (yet?)</a></li>
<li><a class="reference external" href="#note-you-get-an-attributeerror-not-an-importerror">9.1.3. Note: you get an AttributeError, not an ImportError</a></li>
</ul>
</li>
<li><a class="reference external" href="#support-for-interaction-with-system-utilities-binaries">9.2. Support for interaction with system utilities/binaries</a><ul>
<li><a class="reference external" href="#the-shell-based-approach">9.2.1. The shell based approach</a></li>
<li><a class="reference external" href="#local-paths-have-sysexec">9.2.2. local paths have <tt class="docutils literal"><span class="pre">sysexec</span></tt></a></li>
<li><a class="reference external" href="#finding-an-executable-local-path">9.2.3. finding an executable local path</a></li>
</ul>
</li>
<li><a class="reference external" href="#cross-python-version-compatibility-helpers">9.3. Cross-Python Version compatibility helpers</a><ul>
<li><a class="reference external" href="#py-compat">9.3.1. <tt class="docutils literal"><span class="pre">py.compat</span></tt></a></li>
<li><a class="reference external" href="#py-builtin">9.3.2. <tt class="docutils literal"><span class="pre">py.builtin</span></tt></a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="log.html"
title="previous chapter">8. py.log documentation and musings</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="why_py.html"
title="next chapter">10. 1&nbsp;&nbsp;&nbsp;Why, who, what and how do you do <em>the py lib</em>?</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/misc.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="why_py.html" title="10. 1   Why, who, what and how do you do the py lib?"
>next</a> |</li>
<li class="right" >
<a href="log.html" title="8. py.log documentation and musings"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,3 +0,0 @@
# Sphinx inventory version 1
# Project: py lib
# Version: 1.0

View File

@ -1,366 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3. py.path &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="4. py.code" href="code.html" />
<link rel="prev" title="2. py.execnet" href="execnet.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="code.html" title="4. py.code"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-path">
<h1>3. py.path<a class="headerlink" href="#py-path" title="Permalink to this headline"></a></h1>
<p>The &#8216;py&#8217; lib provides a uniform high-level api to deal with filesystems
and filesystem-like interfaces: <tt class="docutils literal"><span class="pre">py.path</span></tt>. It aims to offer a central
object to fs-like object trees (reading from and writing to files, adding
files/directories, examining the types and structure, etc.), and out-of-the-box
provides a number of implementations of this API.</p>
<div class="section" id="path-implementations-provided-by-py-path">
<h2>3.1. Path implementations provided by <tt class="docutils literal"><span class="pre">py.path</span></tt><a class="headerlink" href="#path-implementations-provided-by-py-path" title="Permalink to this headline"></a></h2>
<div class="section" id="py-path-local">
<h3>3.1.1. <tt class="docutils literal"><span class="pre">py.path.local</span></tt><a class="headerlink" href="#py-path-local" title="Permalink to this headline"></a></h3>
<p>The first and most obvious of the implementations is a wrapper around a local
filesystem. It&#8217;s just a bit nicer in usage than the regular Python APIs, and
of course all the functionality is bundled together rather than spread over a
number of modules.</p>
<p>Example usage, here we use the <tt class="docutils literal"><span class="pre">py.test.ensuretemp()</span></tt> function to create
a <tt class="docutils literal"><span class="pre">py.path.local</span></tt> object for us (which wraps a directory):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">py</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">temppath</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">ensuretemp</span><span class="p">(</span><span class="s">&#39;py.path_documentation&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foopath</span> <span class="o">=</span> <span class="n">temppath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;foo&#39;</span><span class="p">)</span> <span class="c"># get child &#39;foo&#39; (lazily)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foopath</span><span class="o">.</span><span class="n">check</span><span class="p">()</span> <span class="c"># check if child &#39;foo&#39; exists</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foopath</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;bar&#39;</span><span class="p">)</span> <span class="c"># write some data to it</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foopath</span><span class="o">.</span><span class="n">check</span><span class="p">()</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foopath</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="go">&#39;bar&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foofile</span> <span class="o">=</span> <span class="n">foopath</span><span class="o">.</span><span class="n">open</span><span class="p">()</span> <span class="c"># return a &#39;real&#39; file object</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foofile</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span>
<span class="go">&#39;b&#39;</span>
</pre></div>
</div>
</div>
<div class="section" id="py-path-svnurl-and-py-path-svnwc">
<h3>3.1.2. <tt class="docutils literal"><span class="pre">py.path.svnurl</span></tt> and <tt class="docutils literal"><span class="pre">py.path.svnwc</span></tt><a class="headerlink" href="#py-path-svnurl-and-py-path-svnwc" title="Permalink to this headline"></a></h3>
<p>Two other <tt class="docutils literal"><span class="pre">py.path</span></tt> implementations that the py lib provides wrap the
popular <a class="reference external" href="http://subversion.tigris.org/">Subversion</a> revision control system: the first (called &#8216;svnurl&#8217;)
by interfacing with a remote server, the second by wrapping a local checkout.
Both allow you to access relatively advanced features such as metadata and
versioning, and both in a way more user-friendly manner than existing other
solutions.</p>
<p>Some example usage of <tt class="docutils literal"><span class="pre">py.path.svnurl</span></tt>:</p>
<div class="highlight-python"><pre>.. &gt;&gt;&gt; import py
.. &gt;&gt;&gt; if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
&gt;&gt;&gt; url = py.path.svnurl('http://codespeak.net/svn/py')
&gt;&gt;&gt; info = url.info()
&gt;&gt;&gt; info.kind
'dir'
&gt;&gt;&gt; firstentry = url.log()[-1]
&gt;&gt;&gt; import time
&gt;&gt;&gt; time.strftime('%Y-%m-%d', time.gmtime(firstentry.date))
'2004-10-02'</pre>
</div>
<p>Example usage of <tt class="docutils literal"><span class="pre">py.path.svnwc</span></tt>:</p>
<div class="highlight-python"><pre>.. &gt;&gt;&gt; if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
&gt;&gt;&gt; temp = py.test.ensuretemp('py.path_documentation')
&gt;&gt;&gt; wc = py.path.svnwc(temp.join('svnwc'))
&gt;&gt;&gt; wc.checkout('http://codespeak.net/svn/py/dist/py/path/local')
&gt;&gt;&gt; wc.join('local.py').check()
True</pre>
</div>
</div>
</div>
<div class="section" id="common-vs-specific-api">
<h2>3.2. Common vs. specific API<a class="headerlink" href="#common-vs-specific-api" title="Permalink to this headline"></a></h2>
<p>All Path objects support a common set of operations, suitable
for many use cases and allowing to transparently switch the
path object within an application (e.g. from &#8220;local&#8221; to &#8220;svnwc&#8221;).
The common set includes functions such as <cite>path.read()</cite> to read all data
from a file, <cite>path.write()</cite> to write data, <cite>path.listdir()</cite> to get a list
of directory entries, <cite>path.check()</cite> to check if a node exists
and is of a particular type, <cite>path.join()</cite> to get
to a (grand)child, <cite>path.visit()</cite> to recursively walk through a node&#8217;s
children, etc. Only things that are not common on &#8216;normal&#8217; filesystems (yet),
such as handling metadata (e.g. the Subversion &#8220;properties&#8221;) require
using specific APIs.</p>
<div class="section" id="examples">
<h3>3.2.1. Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h3>
<p>A quick &#8216;cookbook&#8217; of small examples that will be useful &#8216;in real life&#8217;,
which also presents parts of the &#8216;common&#8217; API, and shows some non-common
methods:</p>
<div class="section" id="searching-txt-files">
<h4>3.2.1.1. Searching <cite>.txt</cite> files<a class="headerlink" href="#searching-txt-files" title="Permalink to this headline"></a></h4>
<p>Search for a particular string inside all files with a .txt extension in a
specific directory.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">dirpath</span> <span class="o">=</span> <span class="n">temppath</span><span class="o">.</span><span class="n">ensure</span><span class="p">(</span><span class="s">&#39;testdir&#39;</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dirpath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;textfile1.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;foo bar baz&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dirpath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;textfile2.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;frob bar spam eggs&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">subdir</span> <span class="o">=</span> <span class="n">dirpath</span><span class="o">.</span><span class="n">ensure</span><span class="p">(</span><span class="s">&#39;subdir&#39;</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">subdir</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;textfile1.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;foo baz&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">subdir</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;textfile2.txt&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;spam eggs spam foo bar spam&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">fpath</span> <span class="ow">in</span> <span class="n">dirpath</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="s">&#39;*.txt&#39;</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">if</span> <span class="s">&#39;bar&#39;</span> <span class="ow">in</span> <span class="n">fpath</span><span class="o">.</span><span class="n">read</span><span class="p">():</span>
<span class="gp">... </span> <span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fpath</span><span class="o">.</span><span class="n">basename</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">results</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">results</span>
<span class="go">[&#39;textfile1.txt&#39;, &#39;textfile2.txt&#39;, &#39;textfile2.txt&#39;]</span>
</pre></div>
</div>
</div>
<div class="section" id="working-with-paths">
<h4>3.2.1.2. Working with Paths<a class="headerlink" href="#working-with-paths" title="Permalink to this headline"></a></h4>
<p>This example shows the <tt class="docutils literal"><span class="pre">py.path</span></tt> features to deal with
filesystem paths Note that the filesystem is never touched,
all operations are performed on a string level (so the paths
don&#8217;t have to exist, either):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">p1</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="p">(</span><span class="s">&#39;/foo/bar&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span> <span class="o">=</span> <span class="n">p1</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;baz/qux&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span> <span class="o">==</span> <span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="p">(</span><span class="s">&#39;/foo/bar/baz/qux&#39;</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sep</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">local</span><span class="o">.</span><span class="n">sep</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span><span class="o">.</span><span class="n">relto</span><span class="p">(</span><span class="n">p1</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">sep</span><span class="p">,</span> <span class="s">&#39;/&#39;</span><span class="p">)</span> <span class="c"># os-specific path sep in the string</span>
<span class="go">&#39;baz/qux&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span><span class="o">.</span><span class="n">bestrelpath</span><span class="p">(</span><span class="n">p1</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">sep</span><span class="p">,</span> <span class="s">&#39;/&#39;</span><span class="p">)</span>
<span class="go">&#39;../..&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">p2</span><span class="o">.</span><span class="n">bestrelpath</span><span class="p">(</span><span class="n">p1</span><span class="p">))</span> <span class="o">==</span> <span class="n">p1</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p3</span> <span class="o">=</span> <span class="n">p1</span> <span class="o">/</span> <span class="s">&#39;baz/qux&#39;</span> <span class="c"># the / operator allows joining, too</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p2</span> <span class="o">==</span> <span class="n">p3</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p4</span> <span class="o">=</span> <span class="n">p1</span> <span class="o">+</span> <span class="s">&quot;.py&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p4</span><span class="o">.</span><span class="n">basename</span> <span class="o">==</span> <span class="s">&quot;bar.py&quot;</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p4</span><span class="o">.</span><span class="n">ext</span> <span class="o">==</span> <span class="s">&quot;.py&quot;</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">p4</span><span class="o">.</span><span class="n">purebasename</span> <span class="o">==</span> <span class="s">&quot;bar&quot;</span>
<span class="go">True</span>
</pre></div>
</div>
<p>This should be possible on every implementation of <tt class="docutils literal"><span class="pre">py.path</span></tt>, so
regardless of whether the implementation wraps a UNIX filesystem, a Windows
one, or a database or object tree, these functions should be available (each
with their own notion of path seperators and dealing with conversions, etc.).</p>
</div>
<div class="section" id="checking-path-types">
<h4>3.2.1.3. Checking path types<a class="headerlink" href="#checking-path-types" title="Permalink to this headline"></a></h4>
<p>Now we will show a bit about the powerful &#8216;check()&#8217; method on paths, which
allows you to check whether a file exists, what type it is, etc.:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span> <span class="o">=</span> <span class="n">temppath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;file1&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">()</span> <span class="c"># does it exist?</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span> <span class="o">=</span> <span class="n">file1</span><span class="o">.</span><span class="n">ensure</span><span class="p">(</span><span class="nb">file</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="c"># &#39;touch&#39; the file</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">()</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="nb">dir</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="c"># is it a dir?</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="nb">file</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="c"># or a file?</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">ext</span><span class="o">=</span><span class="s">&#39;.txt&#39;</span><span class="p">)</span> <span class="c"># check the extension</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">textfile</span> <span class="o">=</span> <span class="n">temppath</span><span class="o">.</span><span class="n">ensure</span><span class="p">(</span><span class="s">&#39;text.txt&#39;</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">textfile</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">ext</span><span class="o">=</span><span class="s">&#39;.txt&#39;</span><span class="p">)</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">file1</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">basename</span><span class="o">=</span><span class="s">&#39;file1&#39;</span><span class="p">)</span> <span class="c"># we can use all the path&#39;s properties here</span>
<span class="go">True</span>
</pre></div>
</div>
</div>
<div class="section" id="setting-svn-properties">
<h4>3.2.1.4. Setting svn-properties<a class="headerlink" href="#setting-svn-properties" title="Permalink to this headline"></a></h4>
<p>As an example of &#8216;uncommon&#8217; methods, we&#8217;ll show how to read and write
properties in an <tt class="docutils literal"><span class="pre">py.path.svnwc</span></tt> instance:</p>
<div class="highlight-python"><pre>.. &gt;&gt;&gt; if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
&gt;&gt;&gt; wc.propget('foo')
''
&gt;&gt;&gt; wc.propset('foo', 'bar')
&gt;&gt;&gt; wc.propget('foo')
'bar'
&gt;&gt;&gt; len(wc.status().prop_modified) # our own props
1
&gt;&gt;&gt; msg = wc.revert() # roll back our changes
&gt;&gt;&gt; len(wc.status().prop_modified)
0</pre>
</div>
</div>
<div class="section" id="svn-authentication">
<h4>3.2.1.5. SVN authentication<a class="headerlink" href="#svn-authentication" title="Permalink to this headline"></a></h4>
<p>Some uncommon functionality can also be provided as extensions, such as SVN
authentication:</p>
<div class="highlight-python"><pre>.. &gt;&gt;&gt; if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
&gt;&gt;&gt; auth = py.path.SvnAuth('anonymous', 'user', cache_auth=False,
... interactive=False)
&gt;&gt;&gt; wc.auth = auth
&gt;&gt;&gt; wc.update() # this should work
&gt;&gt;&gt; path = wc.ensure('thisshouldnotexist.txt')
&gt;&gt;&gt; try:
... path.commit('testing')
... except py.process.cmdexec.Error, e:
... pass
&gt;&gt;&gt; 'authorization failed' in str(e)
True</pre>
</div>
</div>
</div>
</div>
<div class="section" id="known-problems-limitations">
<h2>3.3. Known problems / limitations<a class="headerlink" href="#known-problems-limitations" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>The SVN path objects require the &#8220;svn&#8221; command line,
there is currently no support for python bindings.
Parsing the svn output can lead to problems, particularly
regarding if you have a non-english &#8220;locales&#8221; setting.</li>
<li>While the path objects basically work on windows,
there is no attention yet on making unicode paths
work or deal with the famous &#8220;8.3&#8221; filename issues.</li>
</ul>
</div>
<div class="section" id="future-plans">
<h2>3.4. Future plans<a class="headerlink" href="#future-plans" title="Permalink to this headline"></a></h2>
<p>The Subversion path implementations are based
on the <cite>svn</cite> command line, not on the bindings.
It makes sense now to directly use the bindings.</p>
<p>Moreover, it would be good, also considering
<a class="reference external" href="execnet.html">py.execnet</a> distribution of programs, to
be able to manipulate Windows Paths on Linux
and vice versa. So we&#8217;d like to consider
refactoring the path implementations
to provide this choice (and getting rid
of platform-dependencies as much as possible).</p>
<p>There is some experimental small approach
(<tt class="docutils literal"><span class="pre">py/path/gateway/</span></tt>) aiming at having
a convenient Remote Path implementation
and some considerations about future
works in the according <tt class="docutils literal"><span class="pre">py/path/gateway/TODO.txt</span></tt></p>
<p>There are various hacks out there to have
Memory-Filesystems and even path objects
being directly mountable under Linux (via <cite>fuse</cite>).
However, the Path object implementations
do not internally have a clean abstraction
of going to the filesystem - so with some
refactoring it should become easier to
have very custom Path objects, still offering
the quite full interface without requiring
to know about all details of the full path
implementation.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">3. py.path</a><ul>
<li><a class="reference external" href="#path-implementations-provided-by-py-path">3.1. Path implementations provided by <tt class="docutils literal"><span class="pre">py.path</span></tt></a><ul>
<li><a class="reference external" href="#py-path-local">3.1.1. <tt class="docutils literal"><span class="pre">py.path.local</span></tt></a></li>
<li><a class="reference external" href="#py-path-svnurl-and-py-path-svnwc">3.1.2. <tt class="docutils literal"><span class="pre">py.path.svnurl</span></tt> and <tt class="docutils literal"><span class="pre">py.path.svnwc</span></tt></a></li>
</ul>
</li>
<li><a class="reference external" href="#common-vs-specific-api">3.2. Common vs. specific API</a><ul>
<li><a class="reference external" href="#examples">3.2.1. Examples</a><ul>
<li><a class="reference external" href="#searching-txt-files">3.2.1.1. Searching <cite>.txt</cite> files</a></li>
<li><a class="reference external" href="#working-with-paths">3.2.1.2. Working with Paths</a></li>
<li><a class="reference external" href="#checking-path-types">3.2.1.3. Checking path types</a></li>
<li><a class="reference external" href="#setting-svn-properties">3.2.1.4. Setting svn-properties</a></li>
<li><a class="reference external" href="#svn-authentication">3.2.1.5. SVN authentication</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference external" href="#known-problems-limitations">3.3. Known problems / limitations</a></li>
<li><a class="reference external" href="#future-plans">3.4. Future plans</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="execnet.html"
title="previous chapter">2. py.execnet</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="code.html"
title="next chapter">4. py.code</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/path.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="code.html" title="4. py.code"
>next</a> |</li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,102 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>16.3. py lib 1.0.0: XXX &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="16. Release notes" href="releases.html" />
<link rel="prev" title="16.2. py lib 0.9.2: bugfix release" href="release-0.9.2.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="release-0.9.2.html" title="16.2. py lib 0.9.2: bugfix release"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" accesskey="U">16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-lib-1-0-0-xxx">
<h1>16.3. py lib 1.0.0: XXX<a class="headerlink" href="#py-lib-1-0-0-xxx" title="Permalink to this headline"></a></h1>
<p>Welcome to the 1.0.0 py lib release - a library aiming to
support agile and test-driven python development on various levels.</p>
<p>XXX</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="release-0.9.2.html"
title="previous chapter">16.2. py lib 0.9.2: bugfix release</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/release-0.9.0.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="release-0.9.2.html" title="16.2. py lib 0.9.2: bugfix release"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" >16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,127 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>16.2. py lib 0.9.2: bugfix release &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="16. Release notes" href="releases.html" />
<link rel="next" title="16.3. py lib 1.0.0: XXX" href="release-0.9.0.html" />
<link rel="prev" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more" href="release-1.0.0.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="release-0.9.0.html" title="16.3. py lib 1.0.0: XXX"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="release-1.0.0.html" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" accesskey="U">16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-lib-0-9-2-bugfix-release">
<h1>16.2. py lib 0.9.2: bugfix release<a class="headerlink" href="#py-lib-0-9-2-bugfix-release" title="Permalink to this headline"></a></h1>
<p>Welcome to the 0.9.2 py lib and py.test release -
mainly fixing Windows issues, providing better
packaging and integration with setuptools.</p>
<p>Here is a quick summary of what the py lib provides:</p>
<ul class="simple">
<li>py.test: cross-project testing tool with many advanced features</li>
<li>py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes</li>
<li>py.magic.greenlet: micro-threads on standard CPython (&#8220;stackless-light&#8221;)</li>
<li>py.path: path abstractions over local and subversion files</li>
<li>rich documentation of py&#8217;s exported API</li>
<li>tested against Linux, Win32, OSX, works on python 2.3-2.6</li>
</ul>
<p>See here for more information:</p>
<p>Pypi pages: <a class="reference external" href="http://pypi.python.org/pypi/py/">http://pypi.python.org/pypi/py/</a></p>
<p>Download/Install: <a class="reference external" href="http://codespeak.net/py/0.9.2/download.html">http://codespeak.net/py/0.9.2/download.html</a></p>
<p>Documentation/API: <a class="reference external" href="http://codespeak.net/py/0.9.2/index.html">http://codespeak.net/py/0.9.2/index.html</a></p>
<p>best and have fun,</p>
<p>holger krekel</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="release-1.0.0.html"
title="previous chapter">16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="release-0.9.0.html"
title="next chapter">16.3. py lib 1.0.0: XXX</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/release-0.9.2.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="release-0.9.0.html" title="16.3. py lib 1.0.0: XXX"
>next</a> |</li>
<li class="right" >
<a href="release-1.0.0.html" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" >16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,131 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="16. Release notes" href="releases.html" />
<link rel="next" title="16.2. py lib 0.9.2: bugfix release" href="release-0.9.2.html" />
<link rel="prev" title="16. Release notes" href="releases.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="release-0.9.2.html" title="16.2. py lib 0.9.2: bugfix release"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="releases.html" title="16. Release notes"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" accesskey="U">16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-lib-0-9-0-py-test-distributed-execution-greenlets-and-more">
<h1>16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more<a class="headerlink" href="#py-lib-0-9-0-py-test-distributed-execution-greenlets-and-more" title="Permalink to this headline"></a></h1>
<p>Welcome to the 0.9.0 py lib release - a library aiming to
support agile and test-driven python development on various levels.</p>
<p>Main API/Tool Features:</p>
<ul class="simple">
<li>py.test: cross-project testing tool with many advanced features</li>
<li>py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes</li>
<li>py.magic.greenlet: micro-threads on standard CPython (&#8220;stackless-light&#8221;)</li>
<li>py.path: path abstractions over local and subversion files</li>
<li>rich documentation of py&#8217;s exported API</li>
<li>tested against Linux, OSX and partly against Win32, python 2.3-2.5</li>
</ul>
<p>All these features and their API have extensive documentation,
generated with the new &#8220;apigen&#8221;, which we intend to make accessible
for other python projects as well.</p>
<p>Download/Install: <a class="reference external" href="http://codespeak.net/py/0.9.0/download.html">http://codespeak.net/py/0.9.0/download.html</a>
Documentation/API: <a class="reference external" href="http://codespeak.net/py/0.9.0/index.html">http://codespeak.net/py/0.9.0/index.html</a></p>
<p>Work on the py lib has been partially funded by the
European Union IST programme and by <a class="reference external" href="http://merlinux.de">http://merlinux.de</a>
within the PyPy project.</p>
<p>best, have fun and let us know what you think!</p>
<p>holger krekel, Maciej Fijalkowski,
Guido Wesdorp, Carl Friedrich Bolz</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="releases.html"
title="previous chapter">16. Release notes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="release-0.9.2.html"
title="next chapter">16.2. py lib 0.9.2: bugfix release</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/release-1.0.0.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="release-0.9.2.html" title="16.2. py lib 0.9.2: bugfix release"
>next</a> |</li>
<li class="right" >
<a href="releases.html" title="16. Release notes"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="releases.html" >16. Release notes</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,112 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>16. Release notes &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more" href="release-1.0.0.html" />
<link rel="prev" title="15. Downloading" href="download.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="release-1.0.0.html" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="download.html" title="15. Downloading"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="release-notes">
<h1>16. Release notes<a class="headerlink" href="#release-notes" title="Permalink to this headline"></a></h1>
<p>Contents:</p>
<ul>
<li class="toctree-l1"><a class="reference external" href="release-1.0.0.html">16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more</a></li>
<li class="toctree-l1"><a class="reference external" href="release-0.9.2.html">16.2. py lib 0.9.2: bugfix release</a></li>
<li class="toctree-l1"><a class="reference external" href="release-0.9.0.html">16.3. py lib 1.0.0: XXX</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="download.html"
title="previous chapter">15. Downloading</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="release-1.0.0.html"
title="next chapter">16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/releases.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="release-1.0.0.html" title="16.1. py lib 0.9.0: py.test, distributed execution, greenlets and more"
>next</a> |</li>
<li class="right" >
<a href="download.html" title="15. Downloading"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,91 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
<script type="text/javascript" src="searchindex.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,137 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.6. Test configuration &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.7. Working Examples" href="test-examples.html" />
<link rel="prev" title="1.5. Distributed testing" href="test-dist.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-dist.html" title="1.5. Distributed testing"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="test-configuration">
<h1>1.6. Test configuration<a class="headerlink" href="#test-configuration" title="Permalink to this headline"></a></h1>
<div class="section" id="test-options-and-values">
<h2>1.6.1. test options and values<a class="headerlink" href="#test-options-and-values" title="Permalink to this headline"></a></h2>
<p>You can see all available command line options by running:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span> <span class="o">-</span><span class="n">h</span>
</pre></div>
</div>
<p>py.test will lookup values of options in this order:</p>
<ul class="simple">
<li>option value supplied at command line</li>
<li>content of environment variable <tt class="docutils literal"><span class="pre">PYTEST_OPTION_NAME=...</span></tt></li>
<li><tt class="docutils literal"><span class="pre">name</span> <span class="pre">=</span> <span class="pre">...</span></tt> setting in the nearest <tt class="docutils literal"><span class="pre">conftest.py</span></tt> file.</li>
</ul>
<p>The name of an option usually is the one you find
in the longform of the option, i.e. the name
behind the <tt class="docutils literal"><span class="pre">--</span></tt> double-dash.</p>
<p>IOW, you can set default values for options per project, per
home-directoray, per shell session or per test-run.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.6. Test configuration</a><ul>
<li><a class="reference external" href="#test-options-and-values">1.6.1. test options and values</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-dist.html"
title="previous chapter">1.5. Distributed testing</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-examples.html"
title="next chapter">1.7. Working Examples</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-config.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-examples.html" title="1.7. Working Examples"
>next</a> |</li>
<li class="right" >
<a href="test-dist.html" title="1.5. Distributed testing"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,216 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.5. Distributed testing &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.6. Test configuration" href="test-config.html" />
<link rel="prev" title="1.4. Writing plugins" href="test-ext.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-config.html" title="1.6. Test configuration"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-ext.html" title="1.4. Writing plugins"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="distributed-testing">
<span id="distribute-tests-across-machines"></span><h1>1.5. Distributed testing<a class="headerlink" href="#distributed-testing" title="Permalink to this headline"></a></h1>
<p><tt class="docutils literal"><span class="pre">py.test</span></tt> can ad-hoc distribute test runs to multiple CPUs or remote
machines. This allows to speed up development or to use special resources
of remote machines. Before running tests remotely, <tt class="docutils literal"><span class="pre">py.test</span></tt> efficiently
synchronizes your program source code to the remote place. All test results
are reported back and displayed to your local test session. You may
specify different Python versions and interpreters.</p>
<p>Synchronisation and running of tests only requires
a bare Python installation on the remote side. No
special software is installed - this is realized
by use of the <strong>zero installation</strong> <a class="reference external" href="execnet.html">py.execnet</a> mechanisms.</p>
<div class="section" id="speed-up-test-runs-by-sending-tests-to-multiple-cpus">
<h2>1.5.1. Speed up test runs by sending tests to multiple CPUs<a class="headerlink" href="#speed-up-test-runs-by-sending-tests-to-multiple-cpus" title="Permalink to this headline"></a></h2>
<p>To send tests to multiple CPUs, type:</p>
<div class="highlight-python"><pre>py.test -n NUM</pre>
</div>
<p>Especially for longer running tests or tests requiring
a lot of IO this can lead to considerable speed ups.</p>
</div>
<div class="section" id="running-tests-in-a-python-subprocess">
<h2>1.5.2. Running tests in a Python subprocess<a class="headerlink" href="#running-tests-in-a-python-subprocess" title="Permalink to this headline"></a></h2>
<p>To instantiate a python2.4 sub process and send tests to it, you may type:</p>
<div class="highlight-python"><pre>py.test -d --tx popen//python=python2.4</pre>
</div>
<p>This will start a subprocess which is run with the &#8220;python2.4&#8221;
Python interpreter, found in your system binary lookup path.</p>
<p>If you prefix the &#8211;tx option value like this:</p>
<div class="highlight-python"><pre>--tx 3*popen//python=python2.4</pre>
</div>
<p>then three subprocesses would be created and tests
will be load-balanced across these three processes.</p>
</div>
<div class="section" id="sending-tests-to-remote-ssh-accounts">
<h2>1.5.3. Sending tests to remote SSH accounts<a class="headerlink" href="#sending-tests-to-remote-ssh-accounts" title="Permalink to this headline"></a></h2>
<p>Suppose you have a package <tt class="docutils literal"><span class="pre">mypkg</span></tt> which contains some
tests that you can successfully run locally. And you
have a ssh-reachable machine <tt class="docutils literal"><span class="pre">myhost</span></tt>. Then
you can ad-hoc distribute your tests by typing:</p>
<div class="highlight-python"><pre>py.test -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg</pre>
</div>
<p>This will synchronize your <tt class="docutils literal"><span class="pre">mypkg</span></tt> package directory
to an remote ssh account and then locally collect tests
and send them to remote places for execution.</p>
<p>You can specify multiple <tt class="docutils literal"><span class="pre">--rsyncdir</span></tt> directories
to be sent to the remote side.</p>
</div>
<div class="section" id="sending-tests-to-remote-socket-servers">
<h2>1.5.4. Sending tests to remote Socket Servers<a class="headerlink" href="#sending-tests-to-remote-socket-servers" title="Permalink to this headline"></a></h2>
<p>Download the single-module <a class="reference external" href="http://codespeak.net/svn/py/dist/py/execnet/script/socketserver.py">socketserver.py</a> Python program
and run it like this:</p>
<div class="highlight-python"><pre>python socketserver.py</pre>
</div>
<p>It will tell you that it starts listening on the default
port. You can now on your home machine specify this
new socket host with something like this:</p>
<div class="highlight-python"><pre>py.test -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg</pre>
</div>
</div>
<div class="section" id="running-tests-on-many-platforms-at-once">
<span id="atonce"></span><h2>1.5.5. Running tests on many platforms at once<a class="headerlink" href="#running-tests-on-many-platforms-at-once" title="Permalink to this headline"></a></h2>
<p>The basic command to run tests on multiple platforms is:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span> <span class="o">--</span><span class="n">dist</span><span class="o">=</span><span class="n">each</span> <span class="o">--</span><span class="n">tx</span><span class="o">=</span><span class="n">spec1</span> <span class="o">--</span><span class="n">tx</span><span class="o">=</span><span class="n">spec2</span>
</pre></div>
</div>
<p>If you specify a windows host, an OSX host and a Linux
environment this command will send each tests to all
platforms - and report back failures from all platforms
at once. The provided specifications strings
use the <a class="reference external" href="execnet.html#xspec">xspec syntax</a>.</p>
</div>
<div class="section" id="specifying-test-exec-environments-in-a-conftest-py">
<h2>1.5.6. Specifying test exec environments in a conftest.py<a class="headerlink" href="#specifying-test-exec-environments-in-a-conftest-py" title="Permalink to this headline"></a></h2>
<p>Instead of specifying command line options, you can
put options values in a <tt class="docutils literal"><span class="pre">conftest.py</span></tt> file like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">pytest_option_tx</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;ssh=myhost//python=python2.5&#39;</span><span class="p">,</span> <span class="s">&#39;popen//python=python2.5&#39;</span><span class="p">]</span>
<span class="n">pytest_option_dist</span> <span class="o">=</span> <span class="bp">True</span>
</pre></div>
</div>
<p>Any commandline <tt class="docutils literal"><span class="pre">--tx</span></tt> specifictions will add to the list of available execution
environments.</p>
</div>
<div class="section" id="specifying-rsync-dirs-in-a-conftest-py">
<h2>1.5.7. Specifying &#8220;rsync&#8221; dirs in a conftest.py<a class="headerlink" href="#specifying-rsync-dirs-in-a-conftest-py" title="Permalink to this headline"></a></h2>
<p>In your <tt class="docutils literal"><span class="pre">mypkg/conftest.py</span></tt> you may specify directories to synchronise
or to exclude:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">rsyncdirs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;.&#39;</span><span class="p">,</span> <span class="s">&#39;../plugins&#39;</span><span class="p">]</span>
<span class="n">rsyncignore</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;_cache&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p>These directory specifications are relative to the directory
where the <tt class="docutils literal"><span class="pre">conftest.py</span></tt> is found.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.5. Distributed testing</a><ul>
<li><a class="reference external" href="#speed-up-test-runs-by-sending-tests-to-multiple-cpus">1.5.1. Speed up test runs by sending tests to multiple CPUs</a></li>
<li><a class="reference external" href="#running-tests-in-a-python-subprocess">1.5.2. Running tests in a Python subprocess</a></li>
<li><a class="reference external" href="#sending-tests-to-remote-ssh-accounts">1.5.3. Sending tests to remote SSH accounts</a></li>
<li><a class="reference external" href="#sending-tests-to-remote-socket-servers">1.5.4. Sending tests to remote Socket Servers</a></li>
<li><a class="reference external" href="#running-tests-on-many-platforms-at-once">1.5.5. Running tests on many platforms at once</a></li>
<li><a class="reference external" href="#specifying-test-exec-environments-in-a-conftest-py">1.5.6. Specifying test exec environments in a conftest.py</a></li>
<li><a class="reference external" href="#specifying-rsync-dirs-in-a-conftest-py">1.5.7. Specifying &#8220;rsync&#8221; dirs in a conftest.py</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-ext.html"
title="previous chapter">1.4. Writing plugins</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-config.html"
title="next chapter">1.6. Test configuration</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-dist.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-config.html" title="1.6. Test configuration"
>next</a> |</li>
<li class="right" >
<a href="test-ext.html" title="1.4. Writing plugins"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,168 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.7. Working Examples &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="2. py.execnet" href="execnet.html" />
<link rel="prev" title="1.6. Test configuration" href="test-config.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-config.html" title="1.6. Test configuration"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="working-examples">
<h1>1.7. Working Examples<a class="headerlink" href="#working-examples" title="Permalink to this headline"></a></h1>
<div class="section" id="managing-state-at-module-class-and-method-level">
<h2>1.7.1. managing state at module, class and method level<a class="headerlink" href="#managing-state-at-module-class-and-method-level" title="Permalink to this headline"></a></h2>
<p>Here is a working example for what goes on when you setup modules,
classes and methods:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># [[from py/documentation/example/pytest/test_setup_flow_example.py]]</span>
<span class="k">def</span> <span class="nf">setup_module</span><span class="p">(</span><span class="n">module</span><span class="p">):</span>
<span class="n">module</span><span class="o">.</span><span class="n">TestStateFullThing</span><span class="o">.</span><span class="n">classcount</span> <span class="o">=</span> <span class="mf">0</span>
<span class="k">class</span> <span class="nc">TestStateFullThing</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">setup_class</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
<span class="n">cls</span><span class="o">.</span><span class="n">classcount</span> <span class="o">+=</span> <span class="mf">1</span>
<span class="k">def</span> <span class="nf">teardown_class</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
<span class="n">cls</span><span class="o">.</span><span class="n">classcount</span> <span class="o">-=</span> <span class="mf">1</span>
<span class="k">def</span> <span class="nf">setup_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">method</span><span class="o">.</span><span class="n">func_name</span><span class="p">[</span><span class="mf">5</span><span class="p">:])</span>
<span class="k">def</span> <span class="nf">test_42</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">classcount</span> <span class="o">==</span> <span class="mf">1</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="mf">42</span>
<span class="k">def</span> <span class="nf">test_23</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">classcount</span> <span class="o">==</span> <span class="mf">1</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="mf">23</span>
<span class="k">def</span> <span class="nf">teardown_module</span><span class="p">(</span><span class="n">module</span><span class="p">):</span>
<span class="k">assert</span> <span class="n">module</span><span class="o">.</span><span class="n">TestStateFullThing</span><span class="o">.</span><span class="n">classcount</span> <span class="o">==</span> <span class="mf">0</span>
</pre></div>
</div>
<p>For this example the control flow happens as follows:</p>
<div class="highlight-python"><pre>import test_setup_flow_example
setup_module(test_setup_flow_example)
setup_class(TestStateFullThing)
instance = TestStateFullThing()
setup_method(instance, instance.test_42)
instance.test_42()
setup_method(instance, instance.test_23)
instance.test_23()
teardown_class(TestStateFullThing)
teardown_module(test_setup_flow_example)</pre>
</div>
<p>Note that <tt class="docutils literal"><span class="pre">setup_class(TestStateFullThing)</span></tt> is called and not
<tt class="docutils literal"><span class="pre">TestStateFullThing.setup_class()</span></tt> which would require you
to insert <tt class="docutils literal"><span class="pre">setup_class</span> <span class="pre">=</span> <span class="pre">classmethod(setup_class)</span></tt> to make
your setup function callable. Did we mention that lazyness
is a virtue?</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.7. Working Examples</a><ul>
<li><a class="reference external" href="#managing-state-at-module-class-and-method-level">1.7.1. managing state at module, class and method level</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-config.html"
title="previous chapter">1.6. Test configuration</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="execnet.html"
title="next chapter">2. py.execnet</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-examples.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="execnet.html" title="2. py.execnet"
>next</a> |</li>
<li class="right" >
<a href="test-config.html" title="1.6. Test configuration"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,172 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.4. Writing plugins &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.5. Speed up test runs by sending tests to multiple CPUs" href="test-dist.html" />
<link rel="prev" title="1.3. Included plugins" href="test-plugins.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-dist.html" title="1.5. Speed up test runs by sending tests to multiple CPUs"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-plugins.html" title="1.3. Included plugins"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="writing-plugins">
<h1>1.4. Writing plugins<a class="headerlink" href="#writing-plugins" title="Permalink to this headline"></a></h1>
<div class="section" id="learning-by-examples">
<h2>1.4.1. Learning by examples<a class="headerlink" href="#learning-by-examples" title="Permalink to this headline"></a></h2>
<p>XXX</p>
<div class="section" id="adding-custom-options">
<h3>1.4.1.1. adding custom options<a class="headerlink" href="#adding-custom-options" title="Permalink to this headline"></a></h3>
<p>py.test supports adding of standard <a class="reference external" href="http://docs.python.org/library/optparse.html">optparse</a> Options.
A plugin may implement the <tt class="docutils literal"><span class="pre">addoption</span></tt> hook for registering
custom options:</p>
<div class="highlight-python"><pre>class ConftestPlugin:
def pytest_addoption(self, parser):
parser.addoption("-M", "--myopt", action="store",
help="specify string to set myopt")
def pytest_configure(self, config):
if config.option.myopt:
# do action based on option value</pre>
</div>
</div>
</div>
<div class="section" id="setting-default-values-for-test-options">
<h2>1.4.2. Setting default values for test options<a class="headerlink" href="#setting-default-values-for-test-options" title="Permalink to this headline"></a></h2>
<p>You can see all available command line options by running:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span> <span class="o">-</span><span class="n">h</span>
</pre></div>
</div>
<p>py.test will lookup values of options in this order:</p>
<ul class="simple">
<li>option value supplied at command line</li>
<li>content of environment variable <tt class="docutils literal"><span class="pre">PYTEST_OPTION_NAME=...</span></tt></li>
<li><tt class="docutils literal"><span class="pre">name</span> <span class="pre">=</span> <span class="pre">...</span></tt> setting in the nearest <tt class="docutils literal"><span class="pre">conftest.py</span></tt> file.</li>
</ul>
<p>The name of an option usually is the one you find
in the longform of the option, i.e. the name
behind the <tt class="docutils literal"><span class="pre">--</span></tt> double-dash.</p>
<p>IOW, you can set default values for options per project, per
home-directoray, per shell session or per test-run.</p>
</div>
<div class="section" id="plugin-methods">
<h2>1.4.3. Plugin methods<a class="headerlink" href="#plugin-methods" title="Permalink to this headline"></a></h2>
<p>A Plugin class may implement the following attributes and methods:</p>
<p>XXX</p>
<p><span class="target" id="pytest-event">pytest event</span>:</p>
</div>
<div class="section" id="pytest-events">
<h2>1.4.4. Pytest Events<a class="headerlink" href="#pytest-events" title="Permalink to this headline"></a></h2>
<p>XXX</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.4. Writing plugins</a><ul>
<li><a class="reference external" href="#learning-by-examples">1.4.1. Learning by examples</a><ul>
<li><a class="reference external" href="#adding-custom-options">1.4.1.1. adding custom options</a></li>
</ul>
</li>
<li><a class="reference external" href="#setting-default-values-for-test-options">1.4.2. Setting default values for test options</a></li>
<li><a class="reference external" href="#plugin-methods">1.4.3. Plugin methods</a></li>
<li><a class="reference external" href="#pytest-events">1.4.4. Pytest Events</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-plugins.html"
title="previous chapter">1.3. Included plugins</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-dist.html"
title="next chapter">1.5. Speed up test runs by sending tests to multiple CPUs</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-ext.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-dist.html" title="1.5. Speed up test runs by sending tests to multiple CPUs"
>next</a> |</li>
<li class="right" >
<a href="test-plugins.html" title="1.3. Included plugins"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,371 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.2. Features &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.3. Included plugins" href="test-plugins.html" />
<link rel="prev" title="1.1. Quickstart" href="test-quickstart.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-plugins.html" title="1.3. Included plugins"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-quickstart.html" title="1.1. Quickstart"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="features">
<h1>1.2. Features<a class="headerlink" href="#features" title="Permalink to this headline"></a></h1>
<p>py.test is a standalone-tool that collects and runs tests for
your Python application and modules. py.test works across
linux, windows and osx and on Python 2.3 - Python 2.6.</p>
<p>It aims to support <em>unit-tests</em> and <em>functional tests</em> written
in Python and is used in projects that run more than 10000
tests regularly.</p>
<p>py.test presents a clean and powerful command line interface
and strives to generally make testing a fun effort.</p>
<div class="section" id="automatically-collects-and-executes-tests">
<h2>1.2.1. automatically collects and executes tests<a class="headerlink" href="#automatically-collects-and-executes-tests" title="Permalink to this headline"></a></h2>
<p>py.test discovers tests automatically by inspect specified
directories or files. By default, it collects all python
modules a leading <tt class="docutils literal"><span class="pre">test_</span></tt> or trailing <tt class="docutils literal"><span class="pre">_test</span></tt> filename.
From each test module every function with a leading <tt class="docutils literal"><span class="pre">test_</span></tt>
or class with a leading <tt class="docutils literal"><span class="pre">Test</span></tt> name is collected.</p>
</div>
<div class="section" id="load-balance-tests-to-multiple-cpus">
<h2>1.2.2. load-balance tests to multiple CPUs<a class="headerlink" href="#load-balance-tests-to-multiple-cpus" title="Permalink to this headline"></a></h2>
<p>For large test suites you can distribute your
tests to multiple CPUs by issuing for example:</p>
<div class="highlight-python"><pre>py.test -n 3</pre>
</div>
<p>Read more on <a class="reference external" href="test-dist.html">distributed testing</a>.</p>
</div>
<div class="section" id="distribute-tests-across-machines">
<h2>1.2.3. Distribute tests across machines<a class="headerlink" href="#distribute-tests-across-machines" title="Permalink to this headline"></a></h2>
<p>py.test supports the sending of tests to
remote ssh-accounts or socket servers.
It can <cite>ad-hoc run your test on multiple
platforms one a single test run</cite>. Ad-hoc
means that there are <strong>no installation
requirements whatsoever</strong> on the remote side.</p>
</div>
<div class="section" id="extensive-debugging-support">
<h2>1.2.4. extensive debugging support<a class="headerlink" href="#extensive-debugging-support" title="Permalink to this headline"></a></h2>
<div class="section" id="testing-starts-immediately">
<h3>1.2.4.1. testing starts immediately<a class="headerlink" href="#testing-starts-immediately" title="Permalink to this headline"></a></h3>
<p>Testing starts as soon as the first <tt class="docutils literal"><span class="pre">test</span> <span class="pre">item</span></tt>
is collected. The collection process is iterative
and does not need to complete before your first
test items are executed.</p>
</div>
<div class="section" id="support-for-modules-containing-tests">
<h3>1.2.4.2. support for modules containing tests<a class="headerlink" href="#support-for-modules-containing-tests" title="Permalink to this headline"></a></h3>
<p>As <tt class="docutils literal"><span class="pre">py.test</span></tt> operates as a separate cmdline
tool you can easily have a command line utility and
some tests in the same file.</p>
</div>
<div class="section" id="debug-with-the-print-statement">
<h3>1.2.4.3. debug with the <tt class="docutils literal"><span class="pre">print</span></tt> statement<a class="headerlink" href="#debug-with-the-print-statement" title="Permalink to this headline"></a></h3>
<p>By default, <tt class="docutils literal"><span class="pre">py.test</span></tt> catches text written to stdout/stderr during
the execution of each individual test. This output will only be
displayed however if the test fails; you will not see it
otherwise. This allows you to put debugging print statements in your
code without being overwhelmed by all the output that might be
generated by tests that do not fail.</p>
<p>Each failing test that produced output during the running of the test
will have its output displayed in the <tt class="docutils literal"><span class="pre">recorded</span> <span class="pre">stdout</span></tt> section.</p>
<p>The catching of stdout/stderr output can be disabled using the
<tt class="docutils literal"><span class="pre">--nocapture</span></tt> option to the <tt class="docutils literal"><span class="pre">py.test</span></tt> tool. Any output will
in this case be displayed as soon as it is generated.</p>
</div>
<div class="section" id="test-execution-order">
<h3>1.2.4.4. test execution order<a class="headerlink" href="#test-execution-order" title="Permalink to this headline"></a></h3>
<p>Tests usually run in the order in which they appear in the files.
However, tests should not rely on running one after another, as
this prevents more advanced usages: running tests
distributedly or selectively, or in &#8220;looponfailing&#8221; mode,
will cause them to run in random order.</p>
</div>
<div class="section" id="assert-with-the-assert-statement">
<h3>1.2.4.5. assert with the <tt class="docutils literal"><span class="pre">assert</span></tt> statement<a class="headerlink" href="#assert-with-the-assert-statement" title="Permalink to this headline"></a></h3>
<p><tt class="docutils literal"><span class="pre">py.test</span></tt> allows to use the standard python
<tt class="docutils literal"><span class="pre">assert</span> <span class="pre">statement</span></tt> for verifying expectations
and values in Python tests. For example, you can
write the following in your tests:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s">&#39;attribute&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>to state that your object has a certain <tt class="docutils literal"><span class="pre">attribute</span></tt>. In case this
assertion fails you will see the value of <tt class="docutils literal"><span class="pre">x</span></tt>. Intermediate
values are computed by executing the assert expression a second time.
If you execute code with side effects, e.g. read from a file like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">assert</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="o">!=</span> <span class="s">&#39;...&#39;</span>
</pre></div>
</div>
<p>then you may get a warning from pytest if that assertions
first failed and then succeeded.</p>
</div>
<div class="section" id="asserting-expected-exceptions">
<h3>1.2.4.6. asserting expected exceptions<a class="headerlink" href="#asserting-expected-exceptions" title="Permalink to this headline"></a></h3>
<p>In order to write assertions about exceptions, you use
one of two forms:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">raises</span><span class="p">(</span><span class="ne">Exception</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">raises</span><span class="p">(</span><span class="ne">Exception</span><span class="p">,</span> <span class="s">&quot;func(*args, **kwargs)&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>both of which execute the given function with args and kwargs and
asserts that the given <tt class="docutils literal"><span class="pre">Exception</span></tt> is raised. The reporter will
provide you with helpful output in case of failures such as <em>no
exception</em> or <em>wrong exception</em>.</p>
</div>
<div class="section" id="useful-tracebacks-recursion-detection">
<h3>1.2.4.7. useful tracebacks, recursion detection<a class="headerlink" href="#useful-tracebacks-recursion-detection" title="Permalink to this headline"></a></h3>
<p>A lot of care is taken to present nice tracebacks in case of test
failure. Try:</p>
<div class="highlight-python"><pre>py.test py/doc/example/pytest/failure_demo.py</pre>
</div>
<p>to see a variety of tracebacks, each representing a different
failure situation.</p>
<p><tt class="docutils literal"><span class="pre">py.test</span></tt> uses the same order for presenting tracebacks as Python
itself: the oldest function call is shown first, and the most recent call is
shown last. A <tt class="docutils literal"><span class="pre">py.test</span></tt> reported traceback starts with your
failing test function. If the maximum recursion depth has been
exceeded during the running of a test, for instance because of
infinite recursion, <tt class="docutils literal"><span class="pre">py.test</span></tt> will indicate where in the
code the recursion was taking place. You can inhibit
traceback &#8220;cutting&#8221; magic by supplying <tt class="docutils literal"><span class="pre">--fulltrace</span></tt>.</p>
<p>There is also the possibility of using <tt class="docutils literal"><span class="pre">--tb=short</span></tt> to get regular CPython
tracebacks. Or you can use <tt class="docutils literal"><span class="pre">--tb=no</span></tt> to not show any tracebacks at all.</p>
</div>
<div class="section" id="no-inheritance-requirement">
<h3>1.2.4.8. no inheritance requirement<a class="headerlink" href="#no-inheritance-requirement" title="Permalink to this headline"></a></h3>
<p>Test classes are recognized by their leading <tt class="docutils literal"><span class="pre">Test</span></tt> name. Unlike
<tt class="docutils literal"><span class="pre">unitest.py</span></tt>, you don&#8217;t need to inherit from some base class to make
them be found by the test runner. Besides being easier, it also allows
you to write test classes that subclass from application level
classes.</p>
</div>
<div class="section" id="testing-for-deprecated-apis">
<h3>1.2.4.9. testing for deprecated APIs<a class="headerlink" href="#testing-for-deprecated-apis" title="Permalink to this headline"></a></h3>
<p>In your tests you can use <tt class="docutils literal"><span class="pre">py.test.deprecated_call(func,</span> <span class="pre">*args,</span> <span class="pre">**kwargs)</span></tt>
to test that a particular function call triggers a DeprecationWarning.
This is useful for testing phasing out of old APIs in your projects.</p>
</div>
</div>
<div class="section" id="advanced-test-selection-skipping">
<h2>1.2.5. advanced test selection / skipping<a class="headerlink" href="#advanced-test-selection-skipping" title="Permalink to this headline"></a></h2>
<div class="section" id="dynamically-skipping-tests">
<h3>1.2.5.1. dynamically skipping tests<a class="headerlink" href="#dynamically-skipping-tests" title="Permalink to this headline"></a></h3>
<p>If you want to skip tests you can use <tt class="docutils literal"><span class="pre">py.test.skip</span></tt> within
test or setup functions. Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">skip</span><span class="p">(</span><span class="s">&quot;message&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>You can also use a helper to skip on a failing import:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">docutils</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">importorskip</span><span class="p">(</span><span class="s">&quot;docutils&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>or to skip if a library does not have the right version:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">docutils</span> <span class="o">=</span> <span class="n">py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">importorskip</span><span class="p">(</span><span class="s">&quot;docutils&quot;</span><span class="p">,</span> <span class="n">minversion</span><span class="o">=</span><span class="s">&quot;0.3&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The version will be read from the module&#8217;s <tt class="docutils literal"><span class="pre">__version__</span></tt> attribute.</p>
</div>
<div class="section" id="selecting-unselecting-tests-by-keyword">
<span id="selection-by-keyword"></span><h3>1.2.5.2. selecting/unselecting tests by keyword<a class="headerlink" href="#selecting-unselecting-tests-by-keyword" title="Permalink to this headline"></a></h3>
<p>Pytest&#8217;s keyword mechanism provides a powerful way to
group and selectively run tests in your test code base.
You can selectively run tests by specifiying a keyword
on the command line. Examples:</p>
<div class="highlight-python"><pre>py.test -k test_simple
py.test -k "-test_simple"</pre>
</div>
<p>will run all tests matching (or not matching) the
&#8220;test_simple&#8221; keyword. Note that you need to quote
the keyword if &#8220;-&#8221; is recognized as an indicator
for a commandline option. Lastly, you may use:</p>
<div class="highlight-python"><pre>py.test. -k "test_simple:"</pre>
</div>
<p>which will run all tests after the expression has <em>matched once</em>, i.e.
all tests that are seen after a test that matches the &#8220;test_simple&#8221;
keyword.</p>
<p>By default, all filename parts and
class/function names of a test function are put into the set
of keywords for a given test. You may specify additional
kewords like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@py</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">mark</span><span class="p">(</span><span class="n">webtest</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_send_http</span><span class="p">():</span>
<span class="o">...</span>
</pre></div>
</div>
</div>
<div class="section" id="disabling-a-test-class">
<h3>1.2.5.3. disabling a test class<a class="headerlink" href="#disabling-a-test-class" title="Permalink to this headline"></a></h3>
<p>If you want to disable a complete test class you
can set the class-level attribute <tt class="docutils literal"><span class="pre">disabled</span></tt>.
For example, in order to avoid running some tests on Win32:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">TestPosixOnly</span><span class="p">:</span>
<span class="n">disabled</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span> <span class="o">==</span> <span class="s">&#39;win32&#39;</span>
<span class="k">def</span> <span class="nf">test_xxx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="generative-tests-yielding-parametrized-tests">
<h2>1.2.6. generative tests: yielding parametrized tests<a class="headerlink" href="#generative-tests-yielding-parametrized-tests" title="Permalink to this headline"></a></h2>
<p><em>Generative tests</em> are test methods that are <em>generator functions</em> which
<tt class="docutils literal"><span class="pre">yield</span></tt> callables and their arguments. This is most useful for running a
test function multiple times against different parameters. Example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">test_generative</span><span class="p">():</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">(</span><span class="mf">42</span><span class="p">,</span><span class="mf">17</span><span class="p">,</span><span class="mf">49</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">check</span><span class="p">,</span> <span class="n">x</span>
<span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
<span class="k">assert</span> <span class="n">arg</span> <span class="o">%</span> <span class="mf">7</span> <span class="o">==</span> <span class="mf">0</span> <span class="c"># second generated tests fails!</span>
</pre></div>
</div>
<p>Note that <tt class="docutils literal"><span class="pre">test_generative()</span></tt> will cause three tests
to get run, notably <tt class="docutils literal"><span class="pre">check(42)</span></tt>, <tt class="docutils literal"><span class="pre">check(17)</span></tt> and <tt class="docutils literal"><span class="pre">check(49)</span></tt>
of which the middle one will obviously fail.</p>
<p>To make it easier to distinguish the generated tests it is possible to specify an explicit name for them, like for example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">test_generative</span><span class="p">():</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">(</span><span class="mf">42</span><span class="p">,</span><span class="mf">17</span><span class="p">,</span><span class="mf">49</span><span class="p">):</span>
<span class="k">yield</span> <span class="s">&quot;case </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">x</span><span class="p">,</span> <span class="n">check</span><span class="p">,</span> <span class="n">x</span>
</pre></div>
</div>
</div>
<div class="section" id="extensible-plugin-system">
<h2>1.2.7. extensible plugin system<a class="headerlink" href="#extensible-plugin-system" title="Permalink to this headline"></a></h2>
<p>py.test itself consists of many plugins
and you can easily write new <a class="reference external" href="test-plugins.html">py.test plugins</a>
for these purposes:</p>
<ul class="simple">
<li>reporting extensions</li>
<li>customizing collection and run of tests</li>
<li>running non-python tests</li>
<li>managing test state setup</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.2. Features</a><ul>
<li><a class="reference external" href="#automatically-collects-and-executes-tests">1.2.1. automatically collects and executes tests</a></li>
<li><a class="reference external" href="#load-balance-tests-to-multiple-cpus">1.2.2. load-balance tests to multiple CPUs</a></li>
<li><a class="reference external" href="#distribute-tests-across-machines">1.2.3. Distribute tests across machines</a></li>
<li><a class="reference external" href="#extensive-debugging-support">1.2.4. extensive debugging support</a><ul>
<li><a class="reference external" href="#testing-starts-immediately">1.2.4.1. testing starts immediately</a></li>
<li><a class="reference external" href="#support-for-modules-containing-tests">1.2.4.2. support for modules containing tests</a></li>
<li><a class="reference external" href="#debug-with-the-print-statement">1.2.4.3. debug with the <tt class="docutils literal"><span class="pre">print</span></tt> statement</a></li>
<li><a class="reference external" href="#test-execution-order">1.2.4.4. test execution order</a></li>
<li><a class="reference external" href="#assert-with-the-assert-statement">1.2.4.5. assert with the <tt class="docutils literal"><span class="pre">assert</span></tt> statement</a></li>
<li><a class="reference external" href="#asserting-expected-exceptions">1.2.4.6. asserting expected exceptions</a></li>
<li><a class="reference external" href="#useful-tracebacks-recursion-detection">1.2.4.7. useful tracebacks, recursion detection</a></li>
<li><a class="reference external" href="#no-inheritance-requirement">1.2.4.8. no inheritance requirement</a></li>
<li><a class="reference external" href="#testing-for-deprecated-apis">1.2.4.9. testing for deprecated APIs</a></li>
</ul>
</li>
<li><a class="reference external" href="#advanced-test-selection-skipping">1.2.5. advanced test selection / skipping</a><ul>
<li><a class="reference external" href="#dynamically-skipping-tests">1.2.5.1. dynamically skipping tests</a></li>
<li><a class="reference external" href="#selecting-unselecting-tests-by-keyword">1.2.5.2. selecting/unselecting tests by keyword</a></li>
<li><a class="reference external" href="#disabling-a-test-class">1.2.5.3. disabling a test class</a></li>
</ul>
</li>
<li><a class="reference external" href="#generative-tests-yielding-parametrized-tests">1.2.6. generative tests: yielding parametrized tests</a></li>
<li><a class="reference external" href="#extensible-plugin-system">1.2.7. extensible plugin system</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-quickstart.html"
title="previous chapter">1.1. Quickstart</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-plugins.html"
title="next chapter">1.3. Included plugins</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-features.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-plugins.html" title="1.3. Included plugins"
>next</a> |</li>
<li class="right" >
<a href="test-quickstart.html" title="1.1. Quickstart"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,181 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.3. Included plugins &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.4. Learning by examples" href="test-ext.html" />
<link rel="prev" title="1.2. Features" href="test-features.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-ext.html" title="1.4. Learning by examples"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test-features.html" title="1.2. Features"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="included-plugins">
<h1>1.3. Included plugins<a class="headerlink" href="#included-plugins" title="Permalink to this headline"></a></h1>
<p>Many of py.test&#8217;s features are implemented as a plugin.</p>
<div class="section" id="id1">
<h2>1.3.1. Included plugins<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h2>
<p>You can find the source code of all default plugins in
<a class="reference external" href="http://codespeak.net/svn/py/trunk/py/test/plugin/">http://codespeak.net/svn/py/trunk/py/test/plugin/</a></p>
<div class="section" id="plugins-that-add-reporting-asepcts">
<h3>1.3.1.1. plugins that add reporting asepcts<a class="headerlink" href="#plugins-that-add-reporting-asepcts" title="Permalink to this headline"></a></h3>
<p>pytest_terminal: default reporter for writing info to terminals</p>
<p>pytest_resultlog: log test results in machine-readable form to a file</p>
<p>pytest_eventlog: log all internal pytest events to a file</p>
</div>
<div class="section" id="plugins-for-adding-new-test-types">
<h3>1.3.1.2. plugins for adding new test types<a class="headerlink" href="#plugins-for-adding-new-test-types" title="Permalink to this headline"></a></h3>
<p>pytest_unittest: run traditional unittest TestCase instances</p>
<p>pytest_doctest: run doctests in python modules or .txt files</p>
<p>pytest_restdoc: provide RestructuredText syntax and link checking</p>
</div>
<div class="section" id="plugins-for-python-test-functions">
<h3>1.3.1.3. plugins for python test functions<a class="headerlink" href="#plugins-for-python-test-functions" title="Permalink to this headline"></a></h3>
<p>pytest_xfail: provides &#8220;expected to fail&#8221; test marker</p>
<p>pytest_tmpdir: provide temporary directories to test functions</p>
<p>pytest_plugintester: generic plugin apichecks, support for functional plugin tests</p>
<p>pytest_apigen: tracing values of function/method calls when running tests</p>
</div>
</div>
<div class="section" id="loading-plugins-and-specifying-dependencies">
<h2>1.3.2. Loading plugins and specifying dependencies<a class="headerlink" href="#loading-plugins-and-specifying-dependencies" title="Permalink to this headline"></a></h2>
<p>py.test loads and configures plugins at tool startup:</p>
<ul class="simple">
<li>by reading the <tt class="docutils literal"><span class="pre">PYTEST_PLUGINS</span></tt> environment variable
and importing the comma-separated list of plugin names.</li>
<li>by loading all plugins specified via one or more <tt class="docutils literal"><span class="pre">-p</span> <span class="pre">name</span></tt>
command line options.</li>
<li>by loading all plugins specified via a <tt class="docutils literal"><span class="pre">pytest_plugins</span></tt>
variable in <tt class="docutils literal"><span class="pre">conftest.py</span></tt> files or test modules.</li>
</ul>
<div class="section" id="example-ensure-a-plugin-is-loaded">
<h3>1.3.2.1. example: ensure a plugin is loaded<a class="headerlink" href="#example-ensure-a-plugin-is-loaded" title="Permalink to this headline"></a></h3>
<p>If you create a <tt class="docutils literal"><span class="pre">conftest.py</span></tt> file with the following content:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">pytest_plugins</span> <span class="o">=</span> <span class="s">&quot;pytest_myextension&quot;</span><span class="p">,</span>
</pre></div>
</div>
<p>then all tests in that directory and below it will run with
an instantiated &#8220;pytest_myextension&#8221;. Here is how instantiation
takes place:</p>
<ul class="simple">
<li>the module <tt class="docutils literal"><span class="pre">pytest_extension</span></tt> will be imported and
and its contained <cite>ExtensionPlugin`</cite> class will
be instantiated. A plugin module may specify its
dependencies via another <tt class="docutils literal"><span class="pre">pytest_plugins</span></tt> definition.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.3. Included plugins</a><ul>
<li><a class="reference external" href="#id1">1.3.1. Included plugins</a><ul>
<li><a class="reference external" href="#plugins-that-add-reporting-asepcts">1.3.1.1. plugins that add reporting asepcts</a></li>
<li><a class="reference external" href="#plugins-for-adding-new-test-types">1.3.1.2. plugins for adding new test types</a></li>
<li><a class="reference external" href="#plugins-for-python-test-functions">1.3.1.3. plugins for python test functions</a></li>
</ul>
</li>
<li><a class="reference external" href="#loading-plugins-and-specifying-dependencies">1.3.2. Loading plugins and specifying dependencies</a><ul>
<li><a class="reference external" href="#example-ensure-a-plugin-is-loaded">1.3.2.1. example: ensure a plugin is loaded</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test-features.html"
title="previous chapter">1.2. Features</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-ext.html"
title="next chapter">1.4. Learning by examples</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-plugins.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-ext.html" title="1.4. Learning by examples"
>next</a> |</li>
<li class="right" >
<a href="test-features.html" title="1.2. Features"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="contents.html" >Contents</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,155 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1.1. Quickstart &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="up" title="1. py.test" href="test.html" />
<link rel="next" title="1.2. Features" href="test-features.html" />
<link rel="prev" title="1. py.test" href="test.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-features.html" title="1.2. Features"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="test.html" title="1. py.test"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" accesskey="U">1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="quickstart">
<h1>1.1. Quickstart<a class="headerlink" href="#quickstart" title="Permalink to this headline"></a></h1>
<p>This document assumes basic python knowledge. If you have a
<a class="reference external" href="http://pypi.python.org/pypi/setuptools">setuptools installation</a>, install <tt class="docutils literal"><span class="pre">py.test</span></tt> by typing:</p>
<div class="highlight-python"><pre>easy_install -U py</pre>
</div>
<p>For alternative installation methods please see the <a class="reference external" href="download.html">download</a> page.</p>
<p>You should now have a <tt class="docutils literal"><span class="pre">py.test</span></tt> command line tool and can
look at its documented cmdline options via this command:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span> <span class="o">-</span><span class="n">h</span>
</pre></div>
</div>
<div class="section" id="writing-and-running-a-test">
<h2>1.1.1. Writing and running a test<a class="headerlink" href="#writing-and-running-a-test" title="Permalink to this headline"></a></h2>
<p><tt class="docutils literal"><span class="pre">py.test</span></tt> is the command line tool to run tests.
Let&#8217;s write a first test module by putting the following
test function into a <tt class="docutils literal"><span class="pre">test_sample.py</span></tt> file:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c"># content of test_sample.py</span>
<span class="k">def</span> <span class="nf">test_answer</span><span class="p">():</span>
<span class="k">assert</span> <span class="mf">42</span> <span class="o">==</span> <span class="mf">43</span>
</pre></div>
</div>
<p>Now you can run the test by passing it as an argument:</p>
<div class="highlight-python"><pre>py.test test_sample.py</pre>
</div>
<p>What does happen here? <tt class="docutils literal"><span class="pre">py.test</span></tt> looks for functions and
methods in the module that start with <tt class="docutils literal"><span class="pre">test_</span></tt>. It then
executes those tests. Assertions about test outcomes are
done via the standard <tt class="docutils literal"><span class="pre">assert</span></tt> statement.</p>
<p>You can also use <tt class="docutils literal"><span class="pre">py.test</span></tt> to run all tests in a directory structure by
invoking it without any arguments:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">py</span><span class="o">.</span><span class="n">test</span>
</pre></div>
</div>
<p>This will automatically collect and run any Python module whose filenames
start with <tt class="docutils literal"><span class="pre">test_</span></tt> or ends with <tt class="docutils literal"><span class="pre">_test</span></tt> from the directory and any
subdirectories, starting with the current directory, and run them. Each
Python test module is inspected for test methods starting with <tt class="docutils literal"><span class="pre">test_</span></tt>.</p>
<p>Please refer to <a class="reference external" href="test-features.html">features</a> for a walk through the basic features.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">1.1. Quickstart</a><ul>
<li><a class="reference external" href="#writing-and-running-a-test">1.1.1. Writing and running a test</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="test.html"
title="previous chapter">1. py.test</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-features.html"
title="next chapter">1.2. Features</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test-quickstart.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-features.html" title="1.2. Features"
>next</a> |</li>
<li class="right" >
<a href="test.html" title="1. py.test"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
<li><a href="test.html" >1. py.test</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

View File

@ -1,170 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1. py.test &mdash; py lib v1.0.0b1 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '1.0.0b1',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="py lib v1.0.0b1 documentation" href="index.html" />
<link rel="next" title="1.1. Quickstart" href="test-quickstart.html" />
<link rel="prev" title="py lib: Main tools and APIs" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="test-quickstart.html" title="1.1. Quickstart"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="py lib: Main tools and APIs"
accesskey="P">previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="py-test">
<h1>1. py.test<a class="headerlink" href="#py-test" title="Permalink to this headline"></a></h1>
<p><em>py.test</em> is a tool for:</p>
<ul class="simple">
<li>rapidly writing unit- and functional tests in Python</li>
<li>writing tests for non-python code and data</li>
<li>receiving useful reports on test failures</li>
<li>distributing tests to multiple CPUs and remote environments</li>
</ul>
<p><a class="reference external" href="test-quickstart.html">quickstart</a>: for getting started immediately.</p>
<p><a class="reference external" href="test-features.html">features</a>: a walk through basic features and usage.</p>
<p><a class="reference external" href="test-plugins.html">plugins</a>: using available plugins.</p>
<p><a class="reference external" href="test-ext.html">extend</a>: writing plugins and advanced configuration.</p>
<p><a class="reference external" href="test-dist.html">distributed testing</a> how to distribute test runs to other machines and platforms.</p>
<p>Contents:</p>
<ul>
<li class="toctree-l1"><a class="reference external" href="test-quickstart.html">1.1. Quickstart</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-quickstart.html#writing-and-running-a-test">1.1.1. Writing and running a test</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-features.html">1.2. Features</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-features.html#automatically-collects-and-executes-tests">1.2.1. automatically collects and executes tests</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#load-balance-tests-to-multiple-cpus">1.2.2. load-balance tests to multiple CPUs</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#distribute-tests-across-machines">1.2.3. Distribute tests across machines</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#extensive-debugging-support">1.2.4. extensive debugging support</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#advanced-test-selection-skipping">1.2.5. advanced test selection / skipping</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#generative-tests-yielding-parametrized-tests">1.2.6. generative tests: yielding parametrized tests</a></li>
<li class="toctree-l2"><a class="reference external" href="test-features.html#extensible-plugin-system">1.2.7. extensible plugin system</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-plugins.html">1.3. Included plugins</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-plugins.html#id1">1.3.1. Included plugins</a></li>
<li class="toctree-l2"><a class="reference external" href="test-plugins.html#loading-plugins-and-specifying-dependencies">1.3.2. Loading plugins and specifying dependencies</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-ext.html">1.4. Writing plugins</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-ext.html#learning-by-examples">1.4.1. Learning by examples</a></li>
<li class="toctree-l2"><a class="reference external" href="test-ext.html#setting-default-values-for-test-options">1.4.2. Setting default values for test options</a></li>
<li class="toctree-l2"><a class="reference external" href="test-ext.html#plugin-methods">1.4.3. Plugin methods</a></li>
<li class="toctree-l2"><a class="reference external" href="test-ext.html#pytest-events">1.4.4. Pytest Events</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-dist.html">1.5. Distributed testing</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#speed-up-test-runs-by-sending-tests-to-multiple-cpus">1.5.1. Speed up test runs by sending tests to multiple CPUs</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#running-tests-in-a-python-subprocess">1.5.2. Running tests in a Python subprocess</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#sending-tests-to-remote-ssh-accounts">1.5.3. Sending tests to remote SSH accounts</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#sending-tests-to-remote-socket-servers">1.5.4. Sending tests to remote Socket Servers</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#running-tests-on-many-platforms-at-once">1.5.5. Running tests on many platforms at once</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#specifying-test-exec-environments-in-a-conftest-py">1.5.6. Specifying test exec environments in a conftest.py</a></li>
<li class="toctree-l2"><a class="reference external" href="test-dist.html#specifying-rsync-dirs-in-a-conftest-py">1.5.7. Specifying &#8220;rsync&#8221; dirs in a conftest.py</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-config.html">1.6. Test configuration</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-config.html#test-options-and-values">1.6.1. test options and values</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="test-examples.html">1.7. Working Examples</a><ul>
<li class="toctree-l2"><a class="reference external" href="test-examples.html#managing-state-at-module-class-and-method-level">1.7.1. managing state at module, class and method level</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="impl-test.html">1.8. Implementation and Customization of <tt class="docutils literal"><span class="pre">py.test</span></tt></a><ul>
<li class="toctree-l2"><a class="reference external" href="impl-test.html#collecting-and-running-tests-implementation-remarks">1.8.1. Collecting and running tests / implementation remarks</a></li>
<li class="toctree-l2"><a class="reference external" href="impl-test.html#customizing-the-testing-process">1.8.2. Customizing the testing process</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">py lib: Main tools and APIs</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="test-quickstart.html"
title="next chapter">1.1. Quickstart</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/test.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="test-quickstart.html" title="1.1. Quickstart"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="py lib: Main tools and APIs"
>previous</a> |</li>
<li><a href="index.html">py lib v1.0.0b1 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; Copyright 2009, Holger Krekel.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.7.
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More