====================================
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

.. _sysexec:

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
=============================================

The ``py.builtin`` namespace provides a number of helpers that help to write python code compatible across Python interpreters, mainly Python2 and Python3.  Type ``help(py.builtin)`` on a Python prompt for a the selection of builtins.
