Miscellaneous features of the py lib

Mapping the standard python library into py

The py.std object allows lazy access to standard library modules. 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. You can access any other top-level standard library module this way. This means that you will only trigger imports of modules that are actually needed. Note that no attempt is made to import submodules.

Support for interaction with system utilities/binaries

Currently, the py lib offers two ways to interact with system executables. py.process.cmdexec() invokes the shell in order to execute a string. The other one, 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

local paths have sysexec

In order to synchronously execute an executable file you can use sysexec:

binsvn.sysexec('ls', 'http://codespeak.net/svn')

where binsvn is a path that points to the svn commandline binary. Note that this function does not offer any shell-escaping so you have to pass in already separated arguments.

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:

The compat and builtin namespaces help to write code using newer python features on older python interpreters.

py.compat

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.

py.builtin

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)

py.builtin.BaseException is just Exception before Python 2.5.