pytest2/py/doc/_build/html/misc.html

321 lines
20 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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