summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2010-07-12 10:25:57 +0200
committerMichele Simionato <michele.simionato@gmail.com>2010-07-12 10:25:57 +0200
commitd9cb2ba0701c884855900dadc95ede5b66d9fabf (patch)
tree581fa61ab0febcacd388099b170401ad4065668f
parent76e566e7fc5c55d8f03c24a2416b9583daeb3f07 (diff)
downloadmicheles-d9cb2ba0701c884855900dadc95ede5b66d9fabf.tar.gz
Fixed various bugs (see CHANGES.txt)
-rw-r--r--plac/CHANGES.txt3
-rw-r--r--plac/doc/ishelve2.py43
-rw-r--r--plac/doc/plac.html176
-rw-r--r--plac/doc/plac.pdf913
-rw-r--r--plac/doc/plac.txt11
-rw-r--r--plac/doc/plac_adv.txt4
-rw-r--r--plac/doc/sql_interface.py11
-rw-r--r--plac/plac_ext.py11
-rw-r--r--plac/plac_runner.py58
9 files changed, 721 insertions, 509 deletions
diff --git a/plac/CHANGES.txt b/plac/CHANGES.txt
index e7ef6f6..ddd57e0 100644
--- a/plac/CHANGES.txt
+++ b/plac/CHANGES.txt
@@ -1,6 +1,9 @@
HISTORY
----------
+0.6.1 Fixed the history file location; added the ability to pass a split
+ function; added two forgotten files; added a reference to cmd2 by
+ Catherine Devlin (2010-07-12)
0.6.0 Improvement the interactive experience with full readline support and
custom help. Added support for long running command, via threads and
processes (2010-07-11).
diff --git a/plac/doc/ishelve2.py b/plac/doc/ishelve2.py
new file mode 100644
index 0000000..9b8b57e
--- /dev/null
+++ b/plac/doc/ishelve2.py
@@ -0,0 +1,43 @@
+# ishelve2.py
+import shelve, os, sys, plac
+
+class ShelveInterface(object):
+ "A minimal interface over a shelve object."
+ commands = 'set', 'show', 'showall', 'delete'
+ @plac.annotations(
+ configfile=('path name of the shelve', 'option'))
+ def __init__(self, configfile='~/conf.shelve'):
+ self.fname = os.path.expanduser(configfile)
+ self.__doc__ += '\nOperating on %s.\n.help to see '\
+ 'the available commands.\n' % self.fname
+ def __enter__(self):
+ self.sh = shelve.open(self.fname)
+ return self
+ def __exit__(self, etype, exc, tb):
+ self.sh.close()
+ def set(self, name, value):
+ "set name value"
+ yield 'setting %s=%s' % (name, value)
+ self.sh[name] = value
+ def show(self, *names):
+ "show given parameters"
+ for name in names:
+ yield '%s = %s' % (name, self.sh[name]) # no error checking
+ def showall(self):
+ "show all parameters"
+ for name in self.sh:
+ yield '%s = %s' % (name, self.sh[name])
+ def delete(self, name=None):
+ "delete given parameter (or everything)"
+ if name is None:
+ yield 'deleting everything'
+ self.sh.clear()
+ else:
+ yield 'deleting %s' % name
+ del self.sh[name] # no error checking
+
+main = ShelveInterface # the main 'function' can also be a class!
+
+if __name__ == '__main__':
+ shelve_interface = plac.call(main)
+ plac.Interpreter(shelve_interface).interact()
diff --git a/plac/doc/plac.html b/plac/doc/plac.html
index c63e131..37184e5 100644
--- a/plac/doc/plac.html
+++ b/plac/doc/plac.html
@@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
+<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title>Plac: Parsing the Command Line the Easy Way</title>
<meta name="author" content="Michele Simionato" />
<meta name="date" content="June 2010" />
@@ -431,7 +431,7 @@ h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
</tr>
<tr class="field"><th class="docinfo-name">Requires:</th><td class="field-body">Python 2.3+</td>
</tr>
-<tr class="field"><th class="docinfo-name">Installation:</th><td class="field-body"><tt class="docutils literal">easy_install <span class="pre">-U</span> plac</tt></td>
+<tr class="field"><th class="docinfo-name">Installation:</th><td class="field-body"><tt class="docutils literal"><span class="pre">easy_install</span> <span class="pre">-U</span> <span class="pre">plac</span></tt></td>
</tr>
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">BSD license</td>
</tr>
@@ -525,7 +525,7 @@ if __name__ == '__main__':
sys.exit('Unrecognized arguments: %s' % ' '.join(sys.argv[2:]))
</pre>
-<p>As you see the whole <tt class="docutils literal">if __name__ == '__main__'</tt> block (nine lines)
+<p>As you see the whole <tt class="docutils literal"><span class="pre">if</span> <span class="pre">__name__</span> <span class="pre">==</span> <span class="pre">'__main__'</span></tt> block (nine lines)
is essentially boilerplate that should not exist. Actually I think
the language should recognize the main function and pass to it the
command-line arguments automatically; unfortunaly this is unlikely to
@@ -615,12 +615,12 @@ if __name__ == '__main__':
</pre>
<p>Here I want to perform a query on a database table, by extracting the
-most recent data: it makes sense for <tt class="docutils literal">today</tt> to be a default argument.
-If there is a most used table (in this example a table called <tt class="docutils literal">'product'</tt>)
+most recent data: it makes sense for <tt class="docutils literal"><span class="pre">today</span></tt> to be a default argument.
+If there is a most used table (in this example a table called <tt class="docutils literal"><span class="pre">'product'</span></tt>)
it also makes sense to make it a default argument. Performing the parsing
of the command-line arguments by hand takes 8 ugly lines of boilerplate
(using <a class="reference external" href="http://argparse.googlecode.com">argparse</a> would require about the same number of lines).
-With <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> the entire <tt class="docutils literal">__main__</tt> block reduces to the usual two lines:</p>
+With <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> the entire <tt class="docutils literal"><span class="pre">__main__</span></tt> block reduces to the usual two lines:</p>
<pre class="literal-block">
if __name__ == '__main__':
import plac; plac.call(main)
@@ -680,7 +680,7 @@ let's the machine take care of the details.</p>
the sense that it delivers the programmer from the burden of writing
the parser, but is less of a hack: instead of extracting the parser
from the docstring of the module, it extracts it from the signature of
-the <tt class="docutils literal">main</tt> function.</p>
+the <tt class="docutils literal"><span class="pre">main</span></tt> function.</p>
<p>The idea comes from the <cite>function annotations</cite> concept, a new
feature of Python 3. An example is worth a thousand words, so here
it is:</p>
@@ -698,7 +698,7 @@ if __name__ == '__main__':
import plac; plac.call(main)
</pre>
-<p>Here the arguments of the <tt class="docutils literal">main</tt> function have been annotated with
+<p>Here the arguments of the <tt class="docutils literal"><span class="pre">main</span></tt> function have been annotated with
strings which are intented to be used in the help message:</p>
<pre class="literal-block">
usage: example7_.py [-h] dsn [scripts [scripts ...]]
@@ -740,10 +740,10 @@ if __name__ == '__main__':
import plac; plac.call(main)
</pre>
-<p>Here the argument <tt class="docutils literal">command</tt> has been annotated with the tuple
-<tt class="docutils literal">(&quot;SQL query&quot;, 'option', 'c')</tt>: the first string is the help string
+<p>Here the argument <tt class="docutils literal"><span class="pre">command</span></tt> has been annotated with the tuple
+<tt class="docutils literal"><span class="pre">(&quot;SQL</span> <span class="pre">query&quot;,</span> <span class="pre">'option',</span> <span class="pre">'c')</span></tt>: the first string is the help string
which will appear in the usage message, the second string tells <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>
-that <tt class="docutils literal">command</tt> is an option and the third string that there is also
+that <tt class="docutils literal"><span class="pre">command</span></tt> is an option and the third string that there is also
a short form of the option <tt class="docutils literal"><span class="pre">-c</span></tt>, the long form being <tt class="docutils literal"><span class="pre">--command</span></tt>.
The usage message is the following:</p>
<pre class="literal-block">
@@ -767,7 +767,7 @@ $ python3 example8.py --command=&quot;select * from table&quot; dsn
executing select * from table on dsn
</pre>
<p>The third argument in the function annotation can be omitted: in such
-case it will be assumed to be <tt class="docutils literal">None</tt>. The consequence is that
+case it will be assumed to be <tt class="docutils literal"><span class="pre">None</span></tt>. The consequence is that
the usual dichotomy between long and short options (GNU-style options)
disappears: we get <em>smart options</em>, which have the single character prefix
of short options and behave like both long and short options, since
@@ -808,8 +808,8 @@ $ python3 example6.py -com=&quot;select&quot; dsn
usage: example6.py [-h] [-command COMMAND] dsn
example6.py: error: unrecognized arguments: -com=select
</pre>
-<p>If the option is not passed, the variable <tt class="docutils literal">command</tt>
-will get the value <tt class="docutils literal">None</tt>. However, it is possible to specify a non-trivial
+<p>If the option is not passed, the variable <tt class="docutils literal"><span class="pre">command</span></tt>
+will get the value <tt class="docutils literal"><span class="pre">None</span></tt>. However, it is possible to specify a non-trivial
default. Here is an example:</p>
<pre class="literal-block">
# example8_.py
@@ -843,7 +843,7 @@ executing 'select * from table' on dsn
<div class="section" id="scripts-with-flags">
<h1><a class="toc-backref" href="#id5">Scripts with flags</a></h1>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> is able to recognize flags, i.e. boolean options which are
-<tt class="docutils literal">True</tt> if they are passed to the command line and <tt class="docutils literal">False</tt>
+<tt class="docutils literal"><span class="pre">True</span></tt> if they are passed to the command line and <tt class="docutils literal"><span class="pre">False</span></tt>
if they are absent. Here is an example:</p>
<pre class="literal-block">
# example9.py
@@ -873,12 +873,12 @@ $ python3 example9.py -v dsn
connecting to dsn
</pre>
<p>Notice that it is an error trying to specify a default for flags: the
-default value for a flag is always <tt class="docutils literal">False</tt>. If you feel the need to
+default value for a flag is always <tt class="docutils literal"><span class="pre">False</span></tt>. If you feel the need to
implement non-boolean flags, you should use an option with two
choices, as explained in the &quot;more features&quot; section.</p>
<p>For consistency with the way the usage message is printed, I suggest
you to follow the Flag-Option-Required-Default (FORD) convention: in
-the <tt class="docutils literal">main</tt> function write first the flag arguments, then the option
+the <tt class="docutils literal"><span class="pre">main</span></tt> function write first the flag arguments, then the option
arguments, then the required arguments and finally the default
arguments. This is just a convention and you are not forced to use it,
except for the default arguments (including the varargs) which must
@@ -913,7 +913,7 @@ main.__annotations__ = dict(
<p>One should be careful to match the keys of the annotation dictionary
with the names of the arguments in the annotated function; for lazy
people with Python 2.4 available the simplest way is to use the
-<tt class="docutils literal">plac.annotations</tt> decorator that performs the check for you:</p>
+<tt class="docutils literal"><span class="pre">plac.annotations</span></tt> decorator that performs the check for you:</p>
<pre class="literal-block">
&#64;plac.annotations(
dsn=&quot;Database dsn&quot;,
@@ -922,7 +922,7 @@ def main(dsn, *scripts):
...
</pre>
<p>In the rest of this article I will assume that you are using Python 2.X with
-X &gt;= 4 and I will use the <tt class="docutils literal">plac.annotations</tt> decorator. Notice however
+X &gt;= 4 and I will use the <tt class="docutils literal"><span class="pre">plac.annotations</span></tt> decorator. Notice however
that the core features of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> run even on Python 2.3.</p>
</div>
<div class="section" id="more-features">
@@ -934,19 +934,19 @@ the features of <a class="reference external" href="http://argparse.googlecode.c
in <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>. Until now, I have only showed simple annotations, but in
general an annotation is a 6-tuple of the form</p>
<blockquote>
-<tt class="docutils literal">(help, kind, abbrev, type, choices, metavar)</tt></blockquote>
-<p>where <tt class="docutils literal">help</tt> is the help message, <tt class="docutils literal">kind</tt> is a string in the set {
-<tt class="docutils literal">&quot;flag&quot;</tt>, <tt class="docutils literal">&quot;option&quot;</tt>, <tt class="docutils literal">&quot;positional&quot;</tt>}, <tt class="docutils literal">abbrev</tt> is a
-one-character string or <tt class="docutils literal">None</tt>, <tt class="docutils literal">type</tt> is a callable taking a
+<tt class="docutils literal"><span class="pre">(help,</span> <span class="pre">kind,</span> <span class="pre">abbrev,</span> <span class="pre">type,</span> <span class="pre">choices,</span> <span class="pre">metavar)</span></tt></blockquote>
+<p>where <tt class="docutils literal"><span class="pre">help</span></tt> is the help message, <tt class="docutils literal"><span class="pre">kind</span></tt> is a string in the set {
+<tt class="docutils literal"><span class="pre">&quot;flag&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;option&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;positional&quot;</span></tt>}, <tt class="docutils literal"><span class="pre">abbrev</span></tt> is a
+one-character string or <tt class="docutils literal"><span class="pre">None</span></tt>, <tt class="docutils literal"><span class="pre">type</span></tt> is a callable taking a
string in input,
-<tt class="docutils literal">choices</tt> is a discrete sequence of values and <tt class="docutils literal">metavar</tt> is a string.</p>
-<p><tt class="docutils literal">type</tt> is used to automagically convert the command line arguments
+<tt class="docutils literal"><span class="pre">choices</span></tt> is a discrete sequence of values and <tt class="docutils literal"><span class="pre">metavar</span></tt> is a string.</p>
+<p><tt class="docutils literal"><span class="pre">type</span></tt> is used to automagically convert the command line arguments
from the string type to any Python type; by default there is no
-conversion and <tt class="docutils literal">type=None</tt>.</p>
-<p><tt class="docutils literal">choices</tt> is used to restrict the number of the valid
-options; by default there is no restriction i.e. <tt class="docutils literal">choices=None</tt>.</p>
-<p><tt class="docutils literal">metavar</tt> is used to change the argument name in the usage message
-(and only there); by default the metavar is <tt class="docutils literal">None</tt>: this means that
+conversion and <tt class="docutils literal"><span class="pre">type=None</span></tt>.</p>
+<p><tt class="docutils literal"><span class="pre">choices</span></tt> is used to restrict the number of the valid
+options; by default there is no restriction i.e. <tt class="docutils literal"><span class="pre">choices=None</span></tt>.</p>
+<p><tt class="docutils literal"><span class="pre">metavar</span></tt> is used to change the argument name in the usage message
+(and only there); by default the metavar is <tt class="docutils literal"><span class="pre">None</span></tt>: this means that
the name in the usage message is the same as the argument name,
unless the argument has a default and in such a case is
equal to the stringified form of the default.</p>
@@ -989,7 +989,7 @@ optional arguments:
-h, --help show this help message and exit
</pre>
-<p>Notice that the docstring of the <tt class="docutils literal">main</tt> function has been automatically added
+<p>Notice that the docstring of the <tt class="docutils literal"><span class="pre">main</span></tt> function has been automatically added
to the usage message. Here are a couple of examples of use:</p>
<pre class="literal-block">
$ python example10.py add 1 2 3 4
@@ -1000,13 +1000,13 @@ $ python example10.py ad 1 2 3 4 # a mispelling error
usage: example10.py [-h] {add,mul} [n [n ...]]
example10.py: error: argument operator: invalid choice: 'ad' (choose from 'add', 'mul')
</pre>
-<p><tt class="docutils literal">plac.call</tt> can also be used in doctests like this:</p>
+<p><tt class="docutils literal"><span class="pre">plac.call</span></tt> can also be used in doctests like this:</p>
<pre class="doctest-block">
&gt;&gt;&gt; import plac, example10
&gt;&gt;&gt; plac.call(example10.main, ['add', '1', '2'])
3.0
</pre>
-<p><tt class="docutils literal">plac.call</tt> works for generators too:</p>
+<p><tt class="docutils literal"><span class="pre">plac.call</span></tt> works for generators too:</p>
<pre class="doctest-block">
&gt;&gt;&gt; def main(n):
... for i in range(int(n)):
@@ -1014,12 +1014,12 @@ example10.py: error: argument operator: invalid choice: 'ad' (choose from 'add',
&gt;&gt;&gt; plac.call(main, ['3'])
[0, 1, 2]
</pre>
-<p>Internally <tt class="docutils literal">plac.call</tt> tries to convert the output of the main function
+<p>Internally <tt class="docutils literal"><span class="pre">plac.call</span></tt> tries to convert the output of the main function
into a list, if possible. If the output is not iterable or it is a
string, it is left unchanged, but if it is iterable it is converted.
-In particular, generator objects are exhausted by <tt class="docutils literal">plac.call</tt>.</p>
+In particular, generator objects are exhausted by <tt class="docutils literal"><span class="pre">plac.call</span></tt>.</p>
<p>This behavior avoids mistakes like forgetting of applying
-<tt class="docutils literal">list(result)</tt> to the result of <tt class="docutils literal">plac.call</tt>; moreover it makes
+<tt class="docutils literal"><span class="pre">list(result)</span></tt> to the result of <tt class="docutils literal"><span class="pre">plac.call</span></tt>; moreover it makes
errors visible early, and avoids mistakes in code like the following:</p>
<pre class="literal-block">
try:
@@ -1030,13 +1030,13 @@ except:
<p>Without the &quot;listify&quot; functionality, a main function returning a
generator object would not raise any exception until the generator
is iterated over.</p>
-<p>If you are a fan of lazyness, you can still have it by setting the <tt class="docutils literal">eager</tt>
-flag to <tt class="docutils literal">False</tt>, as in the following example:</p>
+<p>If you are a fan of lazyness, you can still have it by setting the <tt class="docutils literal"><span class="pre">eager</span></tt>
+flag to <tt class="docutils literal"><span class="pre">False</span></tt>, as in the following example:</p>
<pre class="literal-block">
for line in plac.call(main, args, eager=False):
print(line)
</pre>
-<p>If <tt class="docutils literal">main</tt> returns a generator object this example will print each
+<p>If <tt class="docutils literal"><span class="pre">main</span></tt> returns a generator object this example will print each
line as soon as available, whereas the default behaviour is to print
all the lines together and the end of the computation.</p>
</div>
@@ -1044,7 +1044,7 @@ all the lines together and the end of the computation.</p>
<h1><a class="toc-backref" href="#id8">A realistic example</a></h1>
<p>Here is a more realistic script using most of the features of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> to
run SQL queries on a database by relying on <a class="reference external" href="http://www.sqlalchemy.org/">SQLAlchemy</a>. Notice the usage
-of the <tt class="docutils literal">type</tt> feature to automagically convert a SQLAlchemy connection
+of the <tt class="docutils literal"><span class="pre">type</span></tt> feature to automagically convert a SQLAlchemy connection
string into a <a class="reference external" href="http://www.sqlalchemy.org/docs/reference/ext/sqlsoup.html">SqlSoup</a> object:</p>
<pre class="literal-block">
# dbcli.py
@@ -1079,12 +1079,12 @@ if __name__ == '__main__':
</pre>
<p>You can see the <em>yield-is-print</em> pattern here: instead of using
-<tt class="docutils literal">print</tt> in the main function, I use <tt class="docutils literal">yield</tt>, and I perform the
-print in the <tt class="docutils literal">__main__</tt> block. The advantage of the pattern is that
-tests invoking <tt class="docutils literal">plac.call</tt> and checking the result become trivial:
+<tt class="docutils literal"><span class="pre">print</span></tt> in the main function, I use <tt class="docutils literal"><span class="pre">yield</span></tt>, and I perform the
+print in the <tt class="docutils literal"><span class="pre">__main__</span></tt> block. The advantage of the pattern is that
+tests invoking <tt class="docutils literal"><span class="pre">plac.call</span></tt> and checking the result become trivial:
had I performed the printing in the main function, the test would have
-involved an ugly hack like redirecting <tt class="docutils literal">sys.stdout</tt> to a
-<tt class="docutils literal">StringIO</tt> object.</p>
+involved an ugly hack like redirecting <tt class="docutils literal"><span class="pre">sys.stdout</span></tt> to a
+<tt class="docutils literal"><span class="pre">StringIO</span></tt> object.</p>
<p>Here is the usage message:</p>
<pre class="literal-block">
usage: dbcli.py [-h] [-H] [-c SQL] [-d |] db [scripts [scripts ...]]
@@ -1108,7 +1108,7 @@ optional arguments:
<h1><a class="toc-backref" href="#id9">Keyword arguments</a></h1>
<p>Starting from release 0.4, <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> supports keyword arguments. In
practice that means that if your main function has keyword arguments,
-<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> treats specially arguments of the form <tt class="docutils literal">&quot;name=value&quot;</tt> in the
+<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> treats specially arguments of the form <tt class="docutils literal"><span class="pre">&quot;name=value&quot;</span></tt> in the
command line. Here is an example:</p>
<pre class="literal-block">
# example12.py
@@ -1152,7 +1152,7 @@ args=('a1', 'a2')
kw={'name': 'value'}
</pre>
<p>When using keyword arguments, one must be careful to use names which
-are not alreay taken; for instance in this examples the name <tt class="docutils literal">opt</tt>
+are not alreay taken; for instance in this examples the name <tt class="docutils literal"><span class="pre">opt</span></tt>
is taken:</p>
<pre class="literal-block">
$ python example12.py 1 2 kw1=1 kw2=2 opt=0
@@ -1187,7 +1187,7 @@ DEFAULT_SHELVE = os.path.expanduser('~/conf.shelve')
setters='setters param=value')
def main(help, showall, clear, delete, filename=DEFAULT_SHELVE,
*params, **setters):
- &quot;A simple interface to a shelve&quot;
+ &quot;A simple interface to a shelve. Use .help to see the available commands.&quot;
sh = shelve.open(filename)
try:
if not any([help, showall, clear, delete, params, setters]):
@@ -1234,29 +1234,29 @@ if __name__ == '__main__':
implemented a custom help command.</li>
<li>I have changed the prefix character used to recognize the options
to a dot.</li>
-<li>Keyword arguments recognition (in the <tt class="docutils literal">**setters</tt>) is used to make it
+<li>Keyword arguments recognition (in the <tt class="docutils literal"><span class="pre">**setters</span></tt>) is used to make it
possible to store a value in the shelve with the syntax
-<tt class="docutils literal">param_name=param_value</tt>.</li>
-<li><tt class="docutils literal">*params</tt> are used to retrieve parameters from the shelve and some
+<tt class="docutils literal"><span class="pre">param_name=param_value</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">*params</span></tt> are used to retrieve parameters from the shelve and some
error checking is performed in the case of missing parameters</li>
-<li>A command to clear the shelve is implemented as a flag (<tt class="docutils literal">.clear</tt>).</li>
+<li>A command to clear the shelve is implemented as a flag (<tt class="docutils literal"><span class="pre">.clear</span></tt>).</li>
<li>A command to delete a given parameter is implemented as an option
-(<tt class="docutils literal">.delete</tt>).</li>
-<li>There is an option with default (<tt class="docutils literal">.filename=conf.shelve</tt>) to store
+(<tt class="docutils literal"><span class="pre">.delete</span></tt>).</li>
+<li>There is an option with default (<tt class="docutils literal"><span class="pre">.filename=conf.shelve</span></tt>) to store
the filename of the shelve.</li>
<li>All things considered, the code looks like a poor man object oriented
interface implemented with a chain of elifs instead of methods. Of course,
<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> can do better than that, but let me start from a low-level approach
first.</li>
</ol>
-<p>If you run <tt class="docutils literal">ishelve.py</tt> without arguments you get the following
+<p>If you run <tt class="docutils literal"><span class="pre">ishelve.py</span></tt> without arguments you get the following
message:</p>
<pre class="literal-block">
$ python ishelve.py
no arguments passed, use .help to see the available commands
</pre>
-<p>If you run <tt class="docutils literal">ishelve.py</tt> with the option <tt class="docutils literal">.h</tt> (or any abbreviation
-of <tt class="docutils literal">.help</tt>) you get:</p>
+<p>If you run <tt class="docutils literal"><span class="pre">ishelve.py</span></tt> with the option <tt class="docutils literal"><span class="pre">.h</span></tt> (or any abbreviation
+of <tt class="docutils literal"><span class="pre">.help</span></tt>) you get:</p>
<pre class="literal-block">
$ python ishelve.py .h
Commands: .help, .showall, .clear, .delete
@@ -1296,7 +1296,7 @@ following assumes knowledge of <a class="reference external" href="http://argpar
<li>plac does not support the destination concept: the destination
coincides with the name of the argument, always. This restriction
has some drawbacks. For instance, suppose you want to define a long
-option called <tt class="docutils literal"><span class="pre">--yield</span></tt>. In this case the destination would be <tt class="docutils literal">yield</tt>,
+option called <tt class="docutils literal"><span class="pre">--yield</span></tt>. In this case the destination would be <tt class="docutils literal"><span class="pre">yield</span></tt>,
which is a Python keyword, and since you cannot introduce an
argument with that name in a function definition, it is impossible
to implement it. Your choices are to change the name of the long
@@ -1307,16 +1307,16 @@ form - normal users expect options to be optional. You should avoid
the use of required options whenever possible.</em> Notice that since
<a class="reference external" href="http://argparse.googlecode.com">argparse</a> supports them, <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> can manage them too, but not directly.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> supports only regular boolean flags. <a class="reference external" href="http://argparse.googlecode.com">argparse</a> has the ability to
-define generalized two-value flags with values different from <tt class="docutils literal">True</tt>
-and <tt class="docutils literal">False</tt>. An earlier version of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> had this feature too, but
+define generalized two-value flags with values different from <tt class="docutils literal"><span class="pre">True</span></tt>
+and <tt class="docutils literal"><span class="pre">False</span></tt>. An earlier version of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> had this feature too, but
since you can use options with two choices instead, and in any case
-the conversion from <tt class="docutils literal">{True, False}</tt> to any couple of values
+the conversion from <tt class="docutils literal"><span class="pre">{True,</span> <span class="pre">False}</span></tt> to any couple of values
can be trivially implemented with a ternary operator
-(<tt class="docutils literal">value1 if flag else value2</tt>), I have removed it (KISS rules!).</li>
-<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support <tt class="docutils literal">nargs</tt> options directly (it uses them internally,
+(<tt class="docutils literal"><span class="pre">value1</span> <span class="pre">if</span> <span class="pre">flag</span> <span class="pre">else</span> <span class="pre">value2</span></tt>), I have removed it (KISS rules!).</li>
+<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support <tt class="docutils literal"><span class="pre">nargs</span></tt> options directly (it uses them internally,
though, to implement flag recognition). The reason it that all the use
cases of interest to me are covered by <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> and did not feel the need
-to increase the learning curve by adding direct support for <tt class="docutils literal">nargs</tt>.</li>
+to increase the learning curve by adding direct support for <tt class="docutils literal"><span class="pre">nargs</span></tt>.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does support subparsers, but you must read the <a class="reference external" href="in-writing">advanced usage
document</a> to see how it works.</li>
<li><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not support actions directly. This also
@@ -1327,14 +1327,14 @@ the <a class="reference external" href="in-writing">advanced usage document</a>
<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> can leverage directly on many <a class="reference external" href="http://argparse.googlecode.com">argparse</a> features.</p>
<p>For instance, you can make invisible an argument in the usage message
simply by using <tt class="docutils literal"><span class="pre">'==SUPPRESS=='</span></tt> as help string (or
-<tt class="docutils literal">argparse.SUPPRESS</tt>). Similarly, you can use <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/other-utilities.html?highlight=filetype#FileType">argparse.FileType</a>
+<tt class="docutils literal"><span class="pre">argparse.SUPPRESS</span></tt>). Similarly, you can use <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/other-utilities.html?highlight=filetype#FileType">argparse.FileType</a>
directly.</p>
<p>It is also possible to pass options to the underlying
-<tt class="docutils literal">argparse.ArgumentParser</tt> object (currently it accepts the default
-arguments <tt class="docutils literal">description</tt>, <tt class="docutils literal">epilog</tt>, <tt class="docutils literal">prog</tt>, <tt class="docutils literal">usage</tt>,
-<tt class="docutils literal">add_help</tt>, <tt class="docutils literal">argument_default</tt>, <tt class="docutils literal">parents</tt>, <tt class="docutils literal">prefix_chars</tt>,
-<tt class="docutils literal">fromfile_prefix_chars</tt>, <tt class="docutils literal">conflict_handler</tt>, <tt class="docutils literal">formatter_class</tt>).
-It is enough to set such attributes on the <tt class="docutils literal">main</tt> function. For
+<tt class="docutils literal"><span class="pre">argparse.ArgumentParser</span></tt> object (currently it accepts the default
+arguments <tt class="docutils literal"><span class="pre">description</span></tt>, <tt class="docutils literal"><span class="pre">epilog</span></tt>, <tt class="docutils literal"><span class="pre">prog</span></tt>, <tt class="docutils literal"><span class="pre">usage</span></tt>,
+<tt class="docutils literal"><span class="pre">add_help</span></tt>, <tt class="docutils literal"><span class="pre">argument_default</span></tt>, <tt class="docutils literal"><span class="pre">parents</span></tt>, <tt class="docutils literal"><span class="pre">prefix_chars</span></tt>,
+<tt class="docutils literal"><span class="pre">fromfile_prefix_chars</span></tt>, <tt class="docutils literal"><span class="pre">conflict_handler</span></tt>, <tt class="docutils literal"><span class="pre">formatter_class</span></tt>).
+It is enough to set such attributes on the <tt class="docutils literal"><span class="pre">main</span></tt> function. For
instance</p>
<pre class="literal-block">
def main(...):
@@ -1347,22 +1347,22 @@ mechanism does not look particularly elegant, but it works well
enough. I assume that the typical user of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> will be happy with
the defaults and would not want to change them; still it is possible
if she wants to.</p>
-<p>For instance, by setting the <tt class="docutils literal">description</tt> attribute, it is possible
+<p>For instance, by setting the <tt class="docutils literal"><span class="pre">description</span></tt> attribute, it is possible
to add a comment to the usage message (by default the docstring of the
-<tt class="docutils literal">main</tt> function is used as description).</p>
+<tt class="docutils literal"><span class="pre">main</span></tt> function is used as description).</p>
<p>It is also possible to change the option prefix; for
instance if your script must run under Windows and you want to use &quot;/&quot;
as option prefix you can add the line:</p>
<pre class="literal-block">
main.prefix_chars='/-'
</pre>
-<p>The first prefix char (<tt class="docutils literal">/</tt>) is used
+<p>The first prefix char (<tt class="docutils literal"><span class="pre">/</span></tt>) is used
as the default for the recognition of options and flags;
-the second prefix char (<tt class="docutils literal">-</tt>) is kept to keep the <tt class="docutils literal"><span class="pre">-h/--help</span></tt> option
+the second prefix char (<tt class="docutils literal"><span class="pre">-</span></tt>) is kept to keep the <tt class="docutils literal"><span class="pre">-h/--help</span></tt> option
working: however you can disable it and reimplement it, if you like,
-as seen in the <tt class="docutils literal">ishelve</tt> example.</p>
+as seen in the <tt class="docutils literal"><span class="pre">ishelve</span></tt> example.</p>
<p>It is possible to access directly the underlying <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html">ArgumentParser</a> object, by
-invoking the <tt class="docutils literal">plac.parser_from</tt> utility function:</p>
+invoking the <tt class="docutils literal"><span class="pre">plac.parser_from</span></tt> utility function:</p>
<pre class="doctest-block">
&gt;&gt;&gt; import plac
&gt;&gt;&gt; def main(arg):
@@ -1371,17 +1371,17 @@ invoking the <tt class="docutils literal">plac.parser_from</tt> utility function
&gt;&gt;&gt; print(plac.parser_from(main)) #doctest: +ELLIPSIS
ArgumentParser(prog=...)
</pre>
-<p>Internally <tt class="docutils literal">plac.call</tt> uses <tt class="docutils literal">plac.parser_from</tt> and adds the parser
-to the main function as an attribute. When <tt class="docutils literal">plac.call(func)</tt> is
+<p>Internally <tt class="docutils literal"><span class="pre">plac.call</span></tt> uses <tt class="docutils literal"><span class="pre">plac.parser_from</span></tt> and adds the parser
+to the main function as an attribute. When <tt class="docutils literal"><span class="pre">plac.call(func)</span></tt> is
invoked multiple time, the parser is re-used and not rebuilt from scratch again.</p>
-<p>I use <tt class="docutils literal">plac.parser_from</tt> in the unit tests of the module, but regular
+<p>I use <tt class="docutils literal"><span class="pre">plac.parser_from</span></tt> in the unit tests of the module, but regular
users should not need to use it, unless they want to access <em>all</em>
of the features of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> directly without calling the main function.</p>
<p>Interested readers should read the documentation of <a class="reference external" href="http://argparse.googlecode.com">argparse</a> to
understand the meaning of the other options. If there is a set of
options that you use very often, you may consider writing a decorator
-adding such options to the <tt class="docutils literal">main</tt> function for you. For simplicity,
-<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not perform any magic except the addition of the <tt class="docutils literal">.p</tt>
+adding such options to the <tt class="docutils literal"><span class="pre">main</span></tt> function for you. For simplicity,
+<a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> does not perform any magic except the addition of the <tt class="docutils literal"><span class="pre">.p</span></tt>
attribute.</p>
</div>
<div class="section" id="plac-vs-the-rest-of-the-world">
@@ -1402,6 +1402,10 @@ no match for the capabilities of <a class="reference external" href="http://pypi
line. For instance <a class="reference external" href="http://pypi.python.org/pypi/Clap/0.7">Clap</a> by Matthew Frazier which appeared on PyPI
just the day before <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>; <a class="reference external" href="http://pypi.python.org/pypi/Clap/0.7">Clap</a> is fine but it is certainly not
easier than <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>.</p>
+<p><a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> can also be used as a replacement of the <a class="reference external" href="http://docs.python.org/library/cmd.html">cmd</a> module in the standard
+library and as such it shares many features with the module <a class="reference external" href="http://packages.python.org/cmd2/">cmd2</a> by
+Catherine Devlin. However, this is completely coincidental, since I became
+aware of the <a class="reference external" href="http://packages.python.org/cmd2/">cmd2</a> module only after writing <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a>.</p>
</div>
<div class="section" id="the-future">
<h1><a class="toc-backref" href="#id13">The future</a></h1>
@@ -1418,10 +1422,10 @@ quite advanced tool with a domain of applicability which far exceeds
the realm of command-line arguments parsers.</p>
<p>Version 0.5 of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> doubled the code base and the documentation: it is
based on the idea of using <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> to implement command-line interpreters,
-i.e. something akin to the <tt class="docutils literal">cmd</tt> module in the standard library, only better.
+i.e. something akin to the <tt class="docutils literal"><span class="pre">cmd</span></tt> module in the standard library, only better.
The new features of <a class="reference external" href="http://pypi.python.org/pypi/plac">plac</a> are described in the <a class="reference external" href="in-writing">advanced usage document</a> .
-They are implemented in a separated module (<tt class="docutils literal">plac_ext.py</tt>), since
-they require Python 2.5 to work, whereas <tt class="docutils literal">plac_core.py</tt> only requires
+They are implemented in a separated module (<tt class="docutils literal"><span class="pre">plac_ext.py</span></tt>), since
+they require Python 2.5 to work, whereas <tt class="docutils literal"><span class="pre">plac_core.py</span></tt> only requires
Python 2.3.</p>
</div>
<div class="section" id="trivia-the-story-behind-the-name">
@@ -1441,8 +1445,8 @@ of functions annotations in Python 3.</li>
</ol>
<p>Putting together these two observations with the original idea of inferring the
parser I decided to build an <a class="reference external" href="http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html">ArgumentParser</a> object from function
-annotations. The <tt class="docutils literal">optionparser</tt> name was ruled out, since I was
-now using <a class="reference external" href="http://argparse.googlecode.com">argparse</a>; a name like <tt class="docutils literal">argparse_plus</tt> was also ruled out,
+annotations. The <tt class="docutils literal"><span class="pre">optionparser</span></tt> name was ruled out, since I was
+now using <a class="reference external" href="http://argparse.googlecode.com">argparse</a>; a name like <tt class="docutils literal"><span class="pre">argparse_plus</span></tt> was also ruled out,
since the typical usage was completely different from the <a class="reference external" href="http://argparse.googlecode.com">argparse</a> usage.</p>
<p>I made a research on PyPI and the name <em>clap</em> (Command Line Arguments Parser)
was not taken, so I renamed everything to clap. After two days
diff --git a/plac/doc/plac.pdf b/plac/doc/plac.pdf
index 836a8d6..b8b99fe 100644
--- a/plac/doc/plac.pdf
+++ b/plac/doc/plac.pdf
@@ -528,10 +528,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 162 0 R
+ /Dest [ 167 0 R
/XYZ
62.69291
- 645.0236
+ 603.0236
0 ]
/Rect [ 62.69291
332.5936
@@ -546,10 +546,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 162 0 R
+ /Dest [ 167 0 R
/XYZ
62.69291
- 645.0236
+ 603.0236
0 ]
/Rect [ 521.4627
332.5936
@@ -564,10 +564,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 162 0 R
+ /Dest [ 167 0 R
/XYZ
62.69291
- 438.0236
+ 396.0236
0 ]
/Rect [ 62.69291
314.5936
@@ -582,10 +582,10 @@ endobj
0
0 ]
/Contents ()
- /Dest [ 162 0 R
+ /Dest [ 167 0 R
/XYZ
62.69291
- 438.0236
+ 396.0236
0 ]
/Rect [ 521.4627
314.5936
@@ -804,12 +804,12 @@ endobj
45 0 R
46 0 R
47 0 R ]
- /Contents 181 0 R
+ /Contents 186 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -928,12 +928,12 @@ endobj
53 0 R
54 0 R
55 0 R ]
- /Contents 182 0 R
+ /Contents 187 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1043,12 +1043,12 @@ endobj
60 0 R
61 0 R
62 0 R ]
- /Contents 183 0 R
+ /Contents 188 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1110,12 +1110,12 @@ endobj
<< /Annots [ 64 0 R
65 0 R
66 0 R ]
- /Contents 184 0 R
+ /Contents 189 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1241,12 +1241,12 @@ endobj
72 0 R
73 0 R
74 0 R ]
- /Contents 185 0 R
+ /Contents 190 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1276,12 +1276,12 @@ endobj
77 0 obj
% Page dictionary
<< /Annots [ 76 0 R ]
- /Contents 186 0 R
+ /Contents 191 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1311,12 +1311,12 @@ endobj
79 0 obj
% Page dictionary
<< /Annots [ 78 0 R ]
- /Contents 187 0 R
+ /Contents 192 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1346,12 +1346,12 @@ endobj
81 0 obj
% Page dictionary
<< /Annots [ 80 0 R ]
- /Contents 188 0 R
+ /Contents 193 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1477,12 +1477,12 @@ endobj
86 0 R
87 0 R
88 0 R ]
- /Contents 189 0 R
+ /Contents 194 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1496,12 +1496,12 @@ endobj
% 'Page10': class PDFPage
90 0 obj
% Page dictionary
-<< /Contents 190 0 R
+<< /Contents 195 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1563,12 +1563,12 @@ endobj
<< /Annots [ 91 0 R
92 0 R
93 0 R ]
- /Contents 191 0 R
+ /Contents 196 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1614,12 +1614,12 @@ endobj
% Page dictionary
<< /Annots [ 95 0 R
96 0 R ]
- /Contents 192 0 R
+ /Contents 197 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1649,12 +1649,12 @@ endobj
99 0 obj
% Page dictionary
<< /Annots [ 98 0 R ]
- /Contents 193 0 R
+ /Contents 198 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1700,12 +1700,12 @@ endobj
% Page dictionary
<< /Annots [ 100 0 R
101 0 R ]
- /Contents 194 0 R
+ /Contents 199 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -1930,7 +1930,7 @@ endobj
117 0 obj
<< /A << /S /URI
/Type /Action
- /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/in-writing) >>
+ /URI (file:///home/msimionato/Dropbox/gcode/plac/in-writing) >>
/Border [ 0
0
0 ]
@@ -1975,7 +1975,7 @@ endobj
120 0 obj
<< /A << /S /URI
/Type /Action
- /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/in-writing) >>
+ /URI (file:///home/msimionato/Dropbox/gcode/plac/in-writing) >>
/Border [ 0
0
0 ]
@@ -1990,7 +1990,7 @@ endobj
121 0 obj
<< /A << /S /URI
/Type /Action
- /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/in-writing) >>
+ /URI (file:///home/msimionato/Dropbox/gcode/plac/in-writing) >>
/Border [ 0
0
0 ]
@@ -2055,12 +2055,12 @@ endobj
121 0 R
122 0 R
123 0 R ]
- /Contents 195 0 R
+ /Contents 200 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -2202,12 +2202,12 @@ endobj
130 0 R
131 0 R
132 0 R ]
- /Contents 196 0 R
+ /Contents 201 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -2346,10 +2346,10 @@ endobj
/Border [ 0
0
0 ]
- /Rect [ 156.6051
- 609.5936
- 177.8606
- 621.5936 ]
+ /Rect [ 62.69291
+ 642.5936
+ 84.4354
+ 654.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
@@ -2357,19 +2357,94 @@ endobj
143 0 obj
<< /A << /S /URI
/Type /Action
+ /URI (http://docs.python.org/library/cmd.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 275.6978
+ 642.5936
+ 297.9903
+ 654.5936 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER122': class PDFDictionary
+144 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://packages.python.org/cmd2/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 203.5285
+ 630.5936
+ 231.1357
+ 642.5936 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER123': class PDFDictionary
+145 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://packages.python.org/cmd2/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 164.4129
+ 618.5936
+ 191.6429
+ 630.5936 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER124': class PDFDictionary
+146 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://pypi.python.org/pypi/plac) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 302.7929
+ 618.5936
+ 321.1329
+ 630.5936 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER125': class PDFDictionary
+147 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://pypi.python.org/pypi/plac) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 156.6051
+ 567.5936
+ 177.8606
+ 579.5936 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER126': class PDFDictionary
+148 0 obj
+<< /A << /S /URI
+ /Type /Action
/URI (http://argparse.googlecode.com) >>
/Border [ 0
0
0 ]
/Rect [ 186.6535
- 585.5936
+ 543.5936
226.1135
- 597.5936 ]
+ 555.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER122': class PDFDictionary
-144 0 obj
+% 'Annot.NUMBER127': class PDFDictionary
+149 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com) >>
@@ -2377,14 +2452,14 @@ endobj
0
0 ]
/Rect [ 493.1227
- 585.5936
+ 543.5936
532.4646
- 597.5936 ]
+ 555.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER123': class PDFDictionary
-145 0 obj
+% 'Annot.NUMBER128': class PDFDictionary
+150 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2392,14 +2467,14 @@ endobj
0
0 ]
/Rect [ 72.7804
- 573.5936
+ 531.5936
96.20788
- 585.5936 ]
+ 543.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER124': class PDFDictionary
-146 0 obj
+% 'Annot.NUMBER129': class PDFDictionary
+151 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2407,14 +2482,14 @@ endobj
0
0 ]
/Rect [ 149.2229
- 543.5936
+ 501.5936
171.2704
- 555.5936 ]
+ 513.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER125': class PDFDictionary
-147 0 obj
+% 'Annot.NUMBER130': class PDFDictionary
+152 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2422,14 +2497,14 @@ endobj
0
0 ]
/Rect [ 128.0309
- 501.5936
+ 459.5936
149.4369
- 513.5936 ]
+ 471.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER126': class PDFDictionary
-148 0 obj
+% 'Annot.NUMBER131': class PDFDictionary
+153 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2437,14 +2512,14 @@ endobj
0
0 ]
/Rect [ 502.8367
- 501.5936
+ 459.5936
524.2427
- 513.5936 ]
+ 471.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER127': class PDFDictionary
-149 0 obj
+% 'Annot.NUMBER132': class PDFDictionary
+154 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2452,29 +2527,29 @@ endobj
0
0 ]
/Rect [ 187.4797
- 477.5936
+ 435.5936
209.0991
- 489.5936 ]
+ 447.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER128': class PDFDictionary
-150 0 obj
+% 'Annot.NUMBER133': class PDFDictionary
+155 0 obj
<< /A << /S /URI
/Type /Action
- /URI (file:///home/micheles/Dropbox/md/gcodedev/plac/in-writing) >>
+ /URI (file:///home/msimionato/Dropbox/gcode/plac/in-writing) >>
/Border [ 0
0
0 ]
/Rect [ 301.6965
- 477.5936
+ 435.5936
426.0446
- 489.5936 ]
+ 447.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER129': class PDFDictionary
-151 0 obj
+% 'Annot.NUMBER134': class PDFDictionary
+156 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2482,14 +2557,14 @@ endobj
0
0 ]
/Rect [ 83.64556
- 402.5936
+ 360.5936
105.7082
- 414.5936 ]
+ 372.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER130': class PDFDictionary
-152 0 obj
+% 'Annot.NUMBER135': class PDFDictionary
+157 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://code.activestate.com/recipes/278844-parsing-the-command-line/) >>
@@ -2497,14 +2572,14 @@ endobj
0
0 ]
/Rect [ 446.6
- 402.5936
+ 360.5936
502.5727
- 414.5936 ]
+ 372.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER131': class PDFDictionary
-153 0 obj
+% 'Annot.NUMBER136': class PDFDictionary
+158 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2512,14 +2587,14 @@ endobj
0
0 ]
/Rect [ 275.6828
- 390.5936
+ 348.5936
297.3688
- 402.5936 ]
+ 360.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER132': class PDFDictionary
-154 0 obj
+% 'Annot.NUMBER137': class PDFDictionary
+159 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://docs.python.org/library/optparse.html?highlight=optionparser#optparse.OptionParser) >>
@@ -2527,14 +2602,14 @@ endobj
0
0 ]
/Rect [ 77.19665
- 378.5936
+ 336.5936
139.4904
- 390.5936 ]
+ 348.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER133': class PDFDictionary
-155 0 obj
+% 'Annot.NUMBER138': class PDFDictionary
+160 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com) >>
@@ -2542,14 +2617,14 @@ endobj
0
0 ]
/Rect [ 96.54131
- 366.5936
+ 324.5936
139.0255
- 378.5936 ]
+ 336.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER134': class PDFDictionary
-156 0 obj
+% 'Annot.NUMBER139': class PDFDictionary
+161 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com) >>
@@ -2557,14 +2632,14 @@ endobj
0
0 ]
/Rect [ 203.5016
- 333.5936
+ 291.5936
245.8453
- 345.5936 ]
+ 303.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER135': class PDFDictionary
-157 0 obj
+% 'Annot.NUMBER140': class PDFDictionary
+162 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html) >>
@@ -2572,14 +2647,14 @@ endobj
0
0 ]
/Rect [ 62.69291
- 258.5936
+ 216.5936
138.7898
- 270.5936 ]
+ 228.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER136': class PDFDictionary
-158 0 obj
+% 'Annot.NUMBER141': class PDFDictionary
+163 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com) >>
@@ -2587,14 +2662,14 @@ endobj
0
0 ]
/Rect [ 114.6649
- 246.5936
+ 204.5936
154.1249
- 258.5936 ]
+ 216.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER137': class PDFDictionary
-159 0 obj
+% 'Annot.NUMBER142': class PDFDictionary
+164 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://argparse.googlecode.com) >>
@@ -2602,14 +2677,14 @@ endobj
0
0 ]
/Rect [ 191.6329
- 234.5936
+ 192.5936
233.8729
- 246.5936 ]
+ 204.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER138': class PDFDictionary
-160 0 obj
+% 'Annot.NUMBER143': class PDFDictionary
+165 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/Clap/0.7) >>
@@ -2617,14 +2692,14 @@ endobj
0
0 ]
/Rect [ 263.3429
- 204.5936
+ 162.5936
286.6829
- 216.5936 ]
+ 174.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
-% 'Annot.NUMBER139': class PDFDictionary
-161 0 obj
+% 'Annot.NUMBER144': class PDFDictionary
+166 0 obj
<< /A << /S /URI
/Type /Action
/URI (http://pypi.python.org/pypi/plac) >>
@@ -2632,14 +2707,14 @@ endobj
0
0 ]
/Rect [ 258.5629
- 156.5936
+ 114.5936
276.9029
- 168.5936 ]
+ 126.5936 ]
/Subtype /Link
/Type /Annot >>
endobj
% 'Page17': class PDFPage
-162 0 obj
+167 0 obj
% Page dictionary
<< /Annots [ 134 0 R
135 0 R
@@ -2668,13 +2743,18 @@ endobj
158 0 R
159 0 R
160 0 R
- 161 0 R ]
- /Contents 197 0 R
+ 161 0 R
+ 162 0 R
+ 163 0 R
+ 164 0 R
+ 165 0 R
+ 166 0 R ]
+ /Contents 202 0 R
/MediaBox [ 0
0
595.2756
841.8898 ]
- /Parent 180 0 R
+ /Parent 185 0 R
/Resources << /Font 1 0 R
/ProcSet [ /PDF
/Text
@@ -2685,199 +2765,199 @@ endobj
/Trans << >>
/Type /Page >>
endobj
-% 'R163': class PDFCatalog
-163 0 obj
+% 'R168': class PDFCatalog
+168 0 obj
% Document Root
-<< /Outlines 165 0 R
- /PageLabels 198 0 R
+<< /Outlines 170 0 R
+ /PageLabels 203 0 R
/PageMode /UseNone
- /Pages 180 0 R
+ /Pages 185 0 R
/Type /Catalog >>
endobj
-% 'R164': class PDFInfo
-164 0 obj
+% 'R169': class PDFInfo
+169 0 obj
<< /Author (Michele Simionato)
- /CreationDate (D:20100703163715-01'00')
+ /CreationDate (D:20100712091726-01'00')
/Keywords ()
/Producer (ReportLab http://www.reportlab.com)
/Subject (\(unspecified\))
/Title (Plac: Parsing the Command Line the Easy Way) >>
endobj
-% 'R165': class PDFOutlines
-165 0 obj
+% 'R170': class PDFOutlines
+170 0 obj
<< /Count 14
- /First 166 0 R
- /Last 179 0 R
+ /First 171 0 R
+ /Last 184 0 R
/Type /Outlines >>
endobj
% 'Outline.0': class OutlineEntryObject
-166 0 obj
+171 0 obj
<< /Dest [ 48 0 R
/XYZ
62.69291
296.0236
0 ]
- /Next 167 0 R
- /Parent 165 0 R
+ /Next 172 0 R
+ /Parent 170 0 R
/Title (The importance of scaling down) >>
endobj
% 'Outline.1': class OutlineEntryObject
-167 0 obj
+172 0 obj
<< /Dest [ 56 0 R
/XYZ
62.69291
615.0236
0 ]
- /Next 168 0 R
- /Parent 165 0 R
- /Prev 166 0 R
+ /Next 173 0 R
+ /Parent 170 0 R
+ /Prev 171 0 R
/Title (Scripts with required arguments) >>
endobj
% 'Outline.2': class OutlineEntryObject
-168 0 obj
+173 0 obj
<< /Dest [ 63 0 R
/XYZ
62.69291
274.2236
0 ]
- /Next 169 0 R
- /Parent 165 0 R
- /Prev 167 0 R
+ /Next 174 0 R
+ /Parent 170 0 R
+ /Prev 172 0 R
/Title (Scripts with default arguments) >>
endobj
% 'Outline.3': class OutlineEntryObject
-169 0 obj
+174 0 obj
<< /Dest [ 75 0 R
/XYZ
62.69291
229.4236
0 ]
- /Next 170 0 R
- /Parent 165 0 R
- /Prev 168 0 R
+ /Next 175 0 R
+ /Parent 170 0 R
+ /Prev 173 0 R
/Title (Scripts with options \(and smart options\)) >>
endobj
% 'Outline.4': class OutlineEntryObject
-170 0 obj
+175 0 obj
<< /Dest [ 79 0 R
/XYZ
62.69291
231.0236
0 ]
- /Next 171 0 R
- /Parent 165 0 R
- /Prev 169 0 R
+ /Next 176 0 R
+ /Parent 170 0 R
+ /Prev 174 0 R
/Title (Scripts with flags) >>
endobj
% 'Outline.5': class OutlineEntryObject
-171 0 obj
+176 0 obj
<< /Dest [ 81 0 R
/XYZ
62.69291
377.4236
0 ]
- /Next 172 0 R
- /Parent 165 0 R
- /Prev 170 0 R
+ /Next 177 0 R
+ /Parent 170 0 R
+ /Prev 175 0 R
/Title (plac for Python 2.X users) >>
endobj
% 'Outline.6': class OutlineEntryObject
-172 0 obj
+177 0 obj
<< /Dest [ 89 0 R
/XYZ
62.69291
647.8236
0 ]
- /Next 173 0 R
- /Parent 165 0 R
- /Prev 171 0 R
+ /Next 178 0 R
+ /Parent 170 0 R
+ /Prev 176 0 R
/Title (More features) >>
endobj
% 'Outline.7': class OutlineEntryObject
-173 0 obj
+178 0 obj
<< /Dest [ 94 0 R
/XYZ
62.69291
683.8236
0 ]
- /Next 174 0 R
- /Parent 165 0 R
- /Prev 172 0 R
+ /Next 179 0 R
+ /Parent 170 0 R
+ /Prev 177 0 R
/Title (A realistic example) >>
endobj
% 'Outline.8': class OutlineEntryObject
-174 0 obj
+179 0 obj
<< /Dest [ 97 0 R
/XYZ
62.69291
623.8236
0 ]
- /Next 175 0 R
- /Parent 165 0 R
- /Prev 173 0 R
+ /Next 180 0 R
+ /Parent 170 0 R
+ /Prev 178 0 R
/Title (Keyword arguments) >>
endobj
% 'Outline.9': class OutlineEntryObject
-175 0 obj
+180 0 obj
<< /Dest [ 99 0 R
/XYZ
62.69291
594.6236
0 ]
- /Next 176 0 R
- /Parent 165 0 R
- /Prev 174 0 R
+ /Next 181 0 R
+ /Parent 170 0 R
+ /Prev 179 0 R
/Title (Final example: a shelve interface) >>
endobj
% 'Outline.10': class OutlineEntryObject
-176 0 obj
+181 0 obj
<< /Dest [ 124 0 R
/XYZ
62.69291
511.8236
0 ]
- /Next 177 0 R
- /Parent 165 0 R
- /Prev 175 0 R
+ /Next 182 0 R
+ /Parent 170 0 R
+ /Prev 180 0 R
/Title (plac vs argparse) >>
endobj
% 'Outline.11': class OutlineEntryObject
-177 0 obj
+182 0 obj
<< /Dest [ 133 0 R
/XYZ
62.69291
161.4236
0 ]
- /Next 178 0 R
- /Parent 165 0 R
- /Prev 176 0 R
+ /Next 183 0 R
+ /Parent 170 0 R
+ /Prev 181 0 R
/Title (plac vs the rest of the world) >>
endobj
% 'Outline.12': class OutlineEntryObject
-178 0 obj
-<< /Dest [ 162 0 R
+183 0 obj
+<< /Dest [ 167 0 R
/XYZ
62.69291
- 645.0236
+ 603.0236
0 ]
- /Next 179 0 R
- /Parent 165 0 R
- /Prev 177 0 R
+ /Next 184 0 R
+ /Parent 170 0 R
+ /Prev 182 0 R
/Title (The future) >>
endobj
% 'Outline.13': class OutlineEntryObject
-179 0 obj
-<< /Dest [ 162 0 R
+184 0 obj
+<< /Dest [ 167 0 R
/XYZ
62.69291
- 438.0236
+ 396.0236
0 ]
- /Parent 165 0 R
- /Prev 178 0 R
+ /Parent 170 0 R
+ /Prev 183 0 R
/Title (Trivia: the story behind the name) >>
endobj
-% 'R180': class PDFPages
-180 0 obj
+% 'R185': class PDFPages
+185 0 obj
% page tree
<< /Count 17
/Kids [ 48 0 R
@@ -2896,11 +2976,11 @@ endobj
102 0 R
124 0 R
133 0 R
- 162 0 R ]
+ 167 0 R ]
/Type /Pages >>
endobj
-% 'R181': class PDFStream
-181 0 obj
+% 'R186': class PDFStream
+186 0 obj
% page stream
<< /Length 9341 >>
stream
@@ -3326,8 +3406,8 @@ Q
endstream
endobj
-% 'R182': class PDFStream
-182 0 obj
+% 'R187': class PDFStream
+187 0 obj
% page stream
<< /Length 4921 >>
stream
@@ -3415,8 +3495,8 @@ Q
endstream
endobj
-% 'R183': class PDFStream
-183 0 obj
+% 'R188': class PDFStream
+188 0 obj
% page stream
<< /Length 4194 >>
stream
@@ -3574,8 +3654,8 @@ Q
endstream
endobj
-% 'R184': class PDFStream
-184 0 obj
+% 'R189': class PDFStream
+189 0 obj
% page stream
<< /Length 3999 >>
stream
@@ -3721,8 +3801,8 @@ Q
endstream
endobj
-% 'R185': class PDFStream
-185 0 obj
+% 'R190': class PDFStream
+190 0 obj
% page stream
<< /Length 4674 >>
stream
@@ -3843,8 +3923,8 @@ Q
endstream
endobj
-% 'R186': class PDFStream
-186 0 obj
+% 'R191': class PDFStream
+191 0 obj
% page stream
<< /Length 4134 >>
stream
@@ -3984,8 +4064,8 @@ Q
endstream
endobj
-% 'R187': class PDFStream
-187 0 obj
+% 'R192': class PDFStream
+192 0 obj
% page stream
<< /Length 4491 >>
stream
@@ -4171,8 +4251,8 @@ Q
endstream
endobj
-% 'R188': class PDFStream
-188 0 obj
+% 'R193': class PDFStream
+193 0 obj
% page stream
<< /Length 5065 >>
stream
@@ -4336,8 +4416,8 @@ Q
endstream
endobj
-% 'R189': class PDFStream
-189 0 obj
+% 'R194': class PDFStream
+194 0 obj
% page stream
<< /Length 5334 >>
stream
@@ -4471,8 +4551,8 @@ Q
endstream
endobj
-% 'R190': class PDFStream
-190 0 obj
+% 'R195': class PDFStream
+195 0 obj
% page stream
<< /Length 4511 >>
stream
@@ -4634,8 +4714,8 @@ Q
endstream
endobj
-% 'R191': class PDFStream
-191 0 obj
+% 'R196': class PDFStream
+196 0 obj
% page stream
<< /Length 4236 >>
stream
@@ -4745,8 +4825,8 @@ Q
endstream
endobj
-% 'R192': class PDFStream
-192 0 obj
+% 'R197': class PDFStream
+197 0 obj
% page stream
<< /Length 3423 >>
stream
@@ -4879,10 +4959,10 @@ Q
endstream
endobj
-% 'R193': class PDFStream
-193 0 obj
+% 'R198': class PDFStream
+198 0 obj
% page stream
-<< /Length 4047 >>
+<< /Length 4089 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -4966,7 +5046,7 @@ q
n -6 -6 492 432 re B*
Q
q
-BT 1 0 0 1 0 413.71 Tm 12 TL /F4 10 Tf 0 0 0 rg (# ishelve.py) Tj T* (import os, shelve, plac) Tj T* T* (DEFAULT_SHELVE = os.path.expanduser\('~/conf.shelve'\)) Tj T* T* (@plac.annotations\() Tj T* ( help=\('show help', 'flag'\),) Tj T* ( showall=\('show all parameters in the shelve', 'flag'\),) Tj T* ( clear=\('clear the shelve', 'flag'\),) Tj T* ( delete=\('delete an element', 'option'\),) Tj T* ( filename=\('filename of the shelve', 'option'\),) Tj T* ( params='names of the parameters in the shelve',) Tj T* ( setters='setters param=value'\)) Tj T* (def main\(help, showall, clear, delete, filename=DEFAULT_SHELVE,) Tj T* ( *params, **setters\):) Tj T* ( "A simple interface to a shelve") Tj T* ( sh = shelve.open\(filename\)) Tj T* ( try:) Tj T* ( if not any\([help, showall, clear, delete, params, setters]\):) Tj T* ( yield 'no arguments passed, use .help to see the available commands') Tj T* ( elif help: # custom help) Tj T* ( yield 'Commands: .help, .showall, .clear, .delete') Tj T* ( yield ') Tj (<) Tj (param) Tj (>) Tj ( ...') Tj T* ( yield ') Tj (<) Tj (param=value) Tj (>) Tj ( ...') Tj T* ( elif showall:) Tj T* ( for param, name in sh.items\(\):) Tj T* ( yield '%s=%s' % \(param, name\)) Tj T* ( elif clear:) Tj T* ( sh.clear\(\)) Tj T* ( yield 'cleared the shelve') Tj T* ( elif delete:) Tj T* ( try:) Tj T* ( del sh[delete]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % delete) Tj T* ET
+BT 1 0 0 1 0 413.71 Tm 12 TL /F4 10 Tf 0 0 0 rg (# ishelve.py) Tj T* (import os, shelve, plac) Tj T* T* (DEFAULT_SHELVE = os.path.expanduser\('~/conf.shelve'\)) Tj T* T* (@plac.annotations\() Tj T* ( help=\('show help', 'flag'\),) Tj T* ( showall=\('show all parameters in the shelve', 'flag'\),) Tj T* ( clear=\('clear the shelve', 'flag'\),) Tj T* ( delete=\('delete an element', 'option'\),) Tj T* ( filename=\('filename of the shelve', 'option'\),) Tj T* ( params='names of the parameters in the shelve',) Tj T* ( setters='setters param=value'\)) Tj T* (def main\(help, showall, clear, delete, filename=DEFAULT_SHELVE,) Tj T* ( *params, **setters\):) Tj T* ( "A simple interface to a shelve. Use .help to see the available commands.") Tj T* ( sh = shelve.open\(filename\)) Tj T* ( try:) Tj T* ( if not any\([help, showall, clear, delete, params, setters]\):) Tj T* ( yield 'no arguments passed, use .help to see the available commands') Tj T* ( elif help: # custom help) Tj T* ( yield 'Commands: .help, .showall, .clear, .delete') Tj T* ( yield ') Tj (<) Tj (param) Tj (>) Tj ( ...') Tj T* ( yield ') Tj (<) Tj (param=value) Tj (>) Tj ( ...') Tj T* ( elif showall:) Tj T* ( for param, name in sh.items\(\):) Tj T* ( yield '%s=%s' % \(param, name\)) Tj T* ( elif clear:) Tj T* ( sh.clear\(\)) Tj T* ( yield 'cleared the shelve') Tj T* ( elif delete:) Tj T* ( try:) Tj T* ( del sh[delete]) Tj T* ( except KeyError:) Tj T* ( yield '%s: not found' % delete) Tj T* ET
Q
Q
Q
@@ -4983,8 +5063,8 @@ Q
endstream
endobj
-% 'R194': class PDFStream
-194 0 obj
+% 'R199': class PDFStream
+199 0 obj
% page stream
<< /Length 6795 >>
stream
@@ -5302,8 +5382,8 @@ Q
endstream
endobj
-% 'R195': class PDFStream
-195 0 obj
+% 'R200': class PDFStream
+200 0 obj
% page stream
<< /Length 7204 >>
stream
@@ -5520,8 +5600,8 @@ Q
endstream
endobj
-% 'R196': class PDFStream
-196 0 obj
+% 'R201': class PDFStream
+201 0 obj
% page stream
<< /Length 6860 >>
stream
@@ -5678,10 +5758,10 @@ Q
endstream
endobj
-% 'R197': class PDFStream
-197 0 obj
+% 'R202': class PDFStream
+202 0 obj
% page stream
-<< /Length 7645 >>
+<< /Length 8225 >>
stream
1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET
q
@@ -5749,49 +5829,55 @@ BT 1 0 0 1 0 28.82 Tm 1.551163 Tw 12 TL /F1 10 Tf 0 0 0 rg (Of course, there are
Q
Q
q
-1 0 0 1 62.69291 624.0236 cm
+1 0 0 1 62.69291 615.0236 cm
+q
+BT 1 0 0 1 0 28.82 Tm .622488 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (can also be used as a replacement of the ) Tj 0 0 .501961 rg (cmd ) Tj 0 0 0 rg (module in the standard library and as such it shares) Tj T* 0 Tw .377126 Tw (many features with the module ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (by Catherine Devlin. However, this is completely coincidental, since) Tj T* 0 Tw (I became aware of the ) Tj 0 0 .501961 rg (cmd2 ) Tj 0 0 0 rg (module only after writing ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 582.0236 cm
q
BT 1 0 0 1 0 8.435 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (The future) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 558.0236 cm
+1 0 0 1 62.69291 516.0236 cm
q
BT 1 0 0 1 0 52.82 Tm .135542 Tw 12 TL /F1 10 Tf 0 0 0 rg (Currently the core of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is around 200 lines of code, not counting blanks, comments and docstrings. I do) Tj T* 0 Tw .968626 Tw (not plan to extend the core much in the future. The idea is to keep the module short: it is and it should) Tj T* 0 Tw .11811 Tw (remain a little wrapper over ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (. Actually I have thought about contributing the core back to ) Tj 0 0 .501961 rg (argparse) Tj T* 0 Tw 2.307485 Tw 0 0 0 rg (if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (becomes successfull and gains a reasonable number of users. For the moment it should be) Tj T* 0 Tw (considered in alpha status.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 516.0236 cm
+1 0 0 1 62.69291 474.0236 cm
q
BT 1 0 0 1 0 28.82 Tm .927488 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice that even if ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (has been designed to be simple to use for simple stuff, its power should not be) Tj T* 0 Tw 1.02186 Tw (underestimated; it is actually a quite advanced tool with a domain of applicability which far exceeds the) Tj T* 0 Tw (realm of command-line arguments parsers.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 450.0236 cm
+1 0 0 1 62.69291 408.0236 cm
q
BT 1 0 0 1 0 52.82 Tm .285988 Tw 12 TL /F1 10 Tf 0 0 0 rg (Version 0.5 of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (doubled the code base and the documentation: it is based on the idea of using ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (to) Tj T* 0 Tw .408555 Tw (implement command-line interpreters, i.e. something akin to the ) Tj /F4 10 Tf (cmd ) Tj /F1 10 Tf (module in the standard library, only) Tj T* 0 Tw .49936 Tw (better. The new features of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (are described in the ) Tj 0 0 .501961 rg (advanced usage document ) Tj 0 0 0 rg (. They are implemented) Tj T* 0 Tw .313828 Tw (in a separated module \() Tj /F4 10 Tf (plac_ext.py) Tj /F1 10 Tf (\), since they require Python 2.5 to work, whereas ) Tj /F4 10 Tf (plac_core.py) Tj T* 0 Tw /F1 10 Tf (only requires Python 2.3.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 417.0236 cm
+1 0 0 1 62.69291 375.0236 cm
q
BT 1 0 0 1 0 8.435 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Trivia: the story behind the name) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 351.0236 cm
+1 0 0 1 62.69291 309.0236 cm
q
BT 1 0 0 1 0 52.82 Tm .942651 Tw 12 TL /F1 10 Tf 0 0 0 rg (The ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (project started very humble: I just wanted to make easy_installable my old ) Tj 0 0 .501961 rg (optionparse ) Tj 0 0 0 rg (recipe,) Tj T* 0 Tw .565988 Tw (and to publish it on PyPI. The original name of ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (was optionparser and the idea behind it was to build) Tj T* 0 Tw .603735 Tw (an ) Tj 0 0 .501961 rg (OptionParser ) Tj 0 0 0 rg (object from the docstring of the module. However, before doing that, I decided to check) Tj T* 0 Tw .244198 Tw (out the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (module, since I knew it was going into Python 2.7 and Python 2.7 was coming out. Soon) Tj T* 0 Tw (enough I realized two things:) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 345.0236 cm
+1 0 0 1 62.69291 303.0236 cm
Q
q
-1 0 0 1 62.69291 345.0236 cm
+1 0 0 1 62.69291 303.0236 cm
Q
q
-1 0 0 1 62.69291 315.0236 cm
+1 0 0 1 62.69291 273.0236 cm
0 0 0 rg
BT /F3 10 Tf 12 TL ET
q
@@ -5811,13 +5897,13 @@ q
Q
Q
q
-1 0 0 1 62.69291 315.0236 cm
+1 0 0 1 62.69291 273.0236 cm
Q
q
-1 0 0 1 62.69291 315.0236 cm
+1 0 0 1 62.69291 273.0236 cm
Q
q
-1 0 0 1 62.69291 285.0236 cm
+1 0 0 1 62.69291 243.0236 cm
0 0 0 rg
BT /F3 10 Tf 12 TL ET
q
@@ -5838,32 +5924,32 @@ q
Q
Q
q
-1 0 0 1 62.69291 285.0236 cm
+1 0 0 1 62.69291 243.0236 cm
Q
q
-1 0 0 1 62.69291 285.0236 cm
+1 0 0 1 62.69291 243.0236 cm
Q
q
-1 0 0 1 62.69291 231.0236 cm
+1 0 0 1 62.69291 189.0236 cm
q
BT 1 0 0 1 0 40.82 Tm .600574 Tw 12 TL /F1 10 Tf 0 0 0 rg (Putting together these two observations with the original idea of inferring the parser I decided to build an) Tj T* 0 Tw .516905 Tw 0 0 .501961 rg (ArgumentParser ) Tj 0 0 0 rg (object from function annotations. The ) Tj /F4 10 Tf (optionparser ) Tj /F1 10 Tf (name was ruled out, since I was) Tj T* 0 Tw 2.085984 Tw (now using ) Tj 0 0 .501961 rg (argparse) Tj 0 0 0 rg (; a name like ) Tj /F4 10 Tf (argparse_plus ) Tj /F1 10 Tf (was also ruled out, since the typical usage was) Tj T* 0 Tw (completely different from the ) Tj 0 0 .501961 rg (argparse ) Tj 0 0 0 rg (usage.) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 201.0236 cm
+1 0 0 1 62.69291 159.0236 cm
q
BT 1 0 0 1 0 16.82 Tm 1.093876 Tw 12 TL /F1 10 Tf 0 0 0 rg (I made a research on PyPI and the name ) Tj /F5 10 Tf (clap ) Tj /F1 10 Tf (\(Command Line Arguments Parser\) was not taken, so I) Tj T* 0 Tw (renamed everything to clap. After two days a ) Tj 0 0 .501961 rg (Clap ) Tj 0 0 0 rg (module appeared on PyPI <) Tj (expletives deleted) Tj (>) Tj (!) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 171.0236 cm
+1 0 0 1 62.69291 129.0236 cm
q
0 0 0 rg
BT 1 0 0 1 0 16.82 Tm /F1 10 Tf 12 TL .877209 Tw (Having little imagination, I decided to rename everything again to plac, an anagram of clap: since it is a) Tj T* 0 Tw (non-existing English name, I hope nobody will steal it from me!) Tj T* ET
Q
Q
q
-1 0 0 1 62.69291 153.0236 cm
+1 0 0 1 62.69291 111.0236 cm
q
BT 1 0 0 1 0 4.82 Tm 12 TL /F1 10 Tf 0 0 0 rg (That's all, I hope you will enjoy working with ) Tj 0 0 .501961 rg (plac) Tj 0 0 0 rg (!) Tj T* ET
Q
@@ -5879,148 +5965,148 @@ Q
endstream
endobj
-% 'R198': class PDFPageLabels
-198 0 obj
+% 'R203': class PDFPageLabels
+203 0 obj
% Document Root
<< /Nums [ 0
- 199 0 R
+ 204 0 R
1
- 200 0 R
+ 205 0 R
2
- 201 0 R
+ 206 0 R
3
- 202 0 R
+ 207 0 R
4
- 203 0 R
+ 208 0 R
5
- 204 0 R
+ 209 0 R
6
- 205 0 R
+ 210 0 R
7
- 206 0 R
+ 211 0 R
8
- 207 0 R
+ 212 0 R
9
- 208 0 R
+ 213 0 R
10
- 209 0 R
+ 214 0 R
11
- 210 0 R
+ 215 0 R
12
- 211 0 R
+ 216 0 R
13
- 212 0 R
+ 217 0 R
14
- 213 0 R
+ 218 0 R
15
- 214 0 R
+ 219 0 R
16
- 215 0 R ] >>
+ 220 0 R ] >>
endobj
-% 'R199': class PDFPageLabel
-199 0 obj
+% 'R204': class PDFPageLabel
+204 0 obj
% None
<< /S /D
/St 1 >>
endobj
-% 'R200': class PDFPageLabel
-200 0 obj
+% 'R205': class PDFPageLabel
+205 0 obj
% None
<< /S /D
/St 2 >>
endobj
-% 'R201': class PDFPageLabel
-201 0 obj
+% 'R206': class PDFPageLabel
+206 0 obj
% None
<< /S /D
/St 3 >>
endobj
-% 'R202': class PDFPageLabel
-202 0 obj
+% 'R207': class PDFPageLabel
+207 0 obj
% None
<< /S /D
/St 4 >>
endobj
-% 'R203': class PDFPageLabel
-203 0 obj
+% 'R208': class PDFPageLabel
+208 0 obj
% None
<< /S /D
/St 5 >>
endobj
-% 'R204': class PDFPageLabel
-204 0 obj
+% 'R209': class PDFPageLabel
+209 0 obj
% None
<< /S /D
/St 6 >>
endobj
-% 'R205': class PDFPageLabel
-205 0 obj
+% 'R210': class PDFPageLabel
+210 0 obj
% None
<< /S /D
/St 7 >>
endobj
-% 'R206': class PDFPageLabel
-206 0 obj
+% 'R211': class PDFPageLabel
+211 0 obj
% None
<< /S /D
/St 8 >>
endobj
-% 'R207': class PDFPageLabel
-207 0 obj
+% 'R212': class PDFPageLabel
+212 0 obj
% None
<< /S /D
/St 9 >>
endobj
-% 'R208': class PDFPageLabel
-208 0 obj
+% 'R213': class PDFPageLabel
+213 0 obj
% None
<< /S /D
/St 10 >>
endobj
-% 'R209': class PDFPageLabel
-209 0 obj
+% 'R214': class PDFPageLabel
+214 0 obj
% None
<< /S /D
/St 11 >>
endobj
-% 'R210': class PDFPageLabel
-210 0 obj
+% 'R215': class PDFPageLabel
+215 0 obj
% None
<< /S /D
/St 12 >>
endobj
-% 'R211': class PDFPageLabel
-211 0 obj
+% 'R216': class PDFPageLabel
+216 0 obj
% None
<< /S /D
/St 13 >>
endobj
-% 'R212': class PDFPageLabel
-212 0 obj
+% 'R217': class PDFPageLabel
+217 0 obj
% None
<< /S /D
/St 14 >>
endobj
-% 'R213': class PDFPageLabel
-213 0 obj
+% 'R218': class PDFPageLabel
+218 0 obj
% None
<< /S /D
/St 15 >>
endobj
-% 'R214': class PDFPageLabel
-214 0 obj
+% 'R219': class PDFPageLabel
+219 0 obj
% None
<< /S /D
/St 16 >>
endobj
-% 'R215': class PDFPageLabel
-215 0 obj
+% 'R220': class PDFPageLabel
+220 0 obj
% None
<< /S /D
/St 17 >>
endobj
xref
-0 216
+0 221
0000000000 65535 f
0000000113 00000 n
0000000258 00000 n
@@ -6139,112 +6225,117 @@ xref
0000029570 00000 n
0000029822 00000 n
0000030075 00000 n
-0000030353 00000 n
-0000030606 00000 n
-0000030860 00000 n
-0000031138 00000 n
-0000031417 00000 n
-0000031671 00000 n
-0000031908 00000 n
-0000032429 00000 n
-0000032747 00000 n
-0000033001 00000 n
-0000033290 00000 n
-0000033542 00000 n
-0000033794 00000 n
-0000034048 00000 n
-0000034302 00000 n
-0000034541 00000 n
-0000034932 00000 n
-0000035191 00000 n
-0000035448 00000 n
-0000035700 00000 n
-0000035954 00000 n
-0000036212 00000 n
-0000036464 00000 n
-0000036722 00000 n
-0000036976 00000 n
-0000037230 00000 n
-0000037482 00000 n
-0000037734 00000 n
-0000037987 00000 n
-0000038241 00000 n
-0000038495 00000 n
-0000038749 00000 n
-0000039003 00000 n
-0000039282 00000 n
-0000039536 00000 n
-0000039823 00000 n
-0000040077 00000 n
-0000040388 00000 n
-0000040640 00000 n
-0000040892 00000 n
-0000041181 00000 n
-0000041433 00000 n
-0000041685 00000 n
-0000041943 00000 n
-0000042182 00000 n
-0000042759 00000 n
-0000042923 00000 n
-0000043197 00000 n
-0000043326 00000 n
-0000043520 00000 n
-0000043731 00000 n
-0000043941 00000 n
-0000044163 00000 n
-0000044361 00000 n
-0000044566 00000 n
-0000044759 00000 n
-0000044958 00000 n
-0000045155 00000 n
-0000045369 00000 n
-0000045567 00000 n
-0000045778 00000 n
-0000045970 00000 n
-0000046153 00000 n
-0000046412 00000 n
-0000055856 00000 n
-0000060880 00000 n
-0000065177 00000 n
-0000069279 00000 n
-0000074056 00000 n
-0000078293 00000 n
-0000082887 00000 n
-0000088055 00000 n
-0000093492 00000 n
-0000098106 00000 n
-0000102445 00000 n
-0000105971 00000 n
-0000110121 00000 n
-0000117019 00000 n
-0000124326 00000 n
-0000131289 00000 n
-0000139041 00000 n
-0000139368 00000 n
-0000139447 00000 n
-0000139526 00000 n
-0000139605 00000 n
-0000139684 00000 n
-0000139763 00000 n
-0000139842 00000 n
-0000139921 00000 n
-0000140000 00000 n
-0000140079 00000 n
-0000140159 00000 n
-0000140239 00000 n
-0000140319 00000 n
-0000140399 00000 n
-0000140479 00000 n
-0000140559 00000 n
-0000140639 00000 n
+0000030349 00000 n
+0000030602 00000 n
+0000030856 00000 n
+0000031130 00000 n
+0000031405 00000 n
+0000031659 00000 n
+0000031896 00000 n
+0000032417 00000 n
+0000032735 00000 n
+0000032989 00000 n
+0000033278 00000 n
+0000033530 00000 n
+0000033782 00000 n
+0000034036 00000 n
+0000034290 00000 n
+0000034529 00000 n
+0000034920 00000 n
+0000035179 00000 n
+0000035436 00000 n
+0000035688 00000 n
+0000035942 00000 n
+0000036200 00000 n
+0000036452 00000 n
+0000036710 00000 n
+0000036964 00000 n
+0000037217 00000 n
+0000037478 00000 n
+0000037732 00000 n
+0000037986 00000 n
+0000038240 00000 n
+0000038494 00000 n
+0000038746 00000 n
+0000038998 00000 n
+0000039251 00000 n
+0000039505 00000 n
+0000039759 00000 n
+0000040013 00000 n
+0000040267 00000 n
+0000040542 00000 n
+0000040796 00000 n
+0000041083 00000 n
+0000041337 00000 n
+0000041648 00000 n
+0000041900 00000 n
+0000042152 00000 n
+0000042441 00000 n
+0000042693 00000 n
+0000042945 00000 n
+0000043203 00000 n
+0000043442 00000 n
+0000044069 00000 n
+0000044233 00000 n
+0000044507 00000 n
+0000044636 00000 n
+0000044830 00000 n
+0000045041 00000 n
+0000045251 00000 n
+0000045473 00000 n
+0000045671 00000 n
+0000045876 00000 n
+0000046069 00000 n
+0000046268 00000 n
+0000046465 00000 n
+0000046679 00000 n
+0000046877 00000 n
+0000047088 00000 n
+0000047280 00000 n
+0000047463 00000 n
+0000047722 00000 n
+0000057166 00000 n
+0000062190 00000 n
+0000066487 00000 n
+0000070589 00000 n
+0000075366 00000 n
+0000079603 00000 n
+0000084197 00000 n
+0000089365 00000 n
+0000094802 00000 n
+0000099416 00000 n
+0000103755 00000 n
+0000107281 00000 n
+0000111473 00000 n
+0000118371 00000 n
+0000125678 00000 n
+0000132641 00000 n
+0000140973 00000 n
+0000141300 00000 n
+0000141379 00000 n
+0000141458 00000 n
+0000141537 00000 n
+0000141616 00000 n
+0000141695 00000 n
+0000141774 00000 n
+0000141853 00000 n
+0000141932 00000 n
+0000142011 00000 n
+0000142091 00000 n
+0000142171 00000 n
+0000142251 00000 n
+0000142331 00000 n
+0000142411 00000 n
+0000142491 00000 n
+0000142571 00000 n
trailer
<< /ID
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
- [(\035U\351\206J$\3719\335\010i\224\201=?\204) (\035U\351\206J$\3719\335\010i\224\201=?\204)]
+ [(\272\236\026\327\302X\352+\277U\362\364\256\2152\272) (\272\236\026\327\302X\352+\277U\362\364\256\2152\272)]
- /Info 164 0 R
- /Root 163 0 R
- /Size 216 >>
+ /Info 169 0 R
+ /Root 168 0 R
+ /Size 221 >>
startxref
-140688
+142620
%%EOF
diff --git a/plac/doc/plac.txt b/plac/doc/plac.txt
index f43d57c..7ae8e44 100644
--- a/plac/doc/plac.txt
+++ b/plac/doc/plac.txt
@@ -3,7 +3,7 @@ Plac: Parsing the Command Line the Easy Way
:Author: Michele Simionato
:E-mail: michele.simionato@gmail.com
-:Date: June 2010
+:Date: July 2010
:Download page: http://pypi.python.org/pypi/plac
:Project page: http://micheles.googlecode.com/hg/plac/doc/plac.html
:Requires: Python 2.3+
@@ -697,7 +697,12 @@ Of course, there are tons of other libraries to parse the command
line. For instance Clap_ by Matthew Frazier which appeared on PyPI
just the day before plac_; Clap_ is fine but it is certainly not
easier than plac_.
-
+
+plac_ can also be used as a replacement of the cmd_ module in the standard
+library and as such it shares many features with the module cmd2_ by
+Catherine Devlin. However, this is completely coincidental, since I became
+aware of the cmd2_ module only after writing plac_.
+
The future
-------------------------------
@@ -769,3 +774,5 @@ That's all, I hope you will enjoy working with plac_!
.. _CLIArgs: http://pypi.python.org/pypi/CLIArgs
.. _opterator: http://pypi.python.org/pypi/opterator
.. _advanced usage document: in-writing
+.. _cmd2: http://packages.python.org/cmd2/
+.. _cmd: http://docs.python.org/library/cmd.html
diff --git a/plac/doc/plac_adv.txt b/plac/doc/plac_adv.txt
index 9ff1dab..3508464 100644
--- a/plac/doc/plac_adv.txt
+++ b/plac/doc/plac_adv.txt
@@ -215,7 +215,9 @@ languages as the ones you can implement with plac_. In particular,
thanks to shlex_, plac_ is able to recognize comments (the default
comment character is ``#``), escape sequences and more. Look at the
shlex_ documentation if you need to customize how the language is
-interpreted.
+interpreted. For more flexibility, it is even possible to pass to the
+interpreter a custom split function with signature ``split(line,
+commentchar)``.
In addition, I have implemented from scratch some support for line number
recognition, so that if a test fail you get the line number of the
diff --git a/plac/doc/sql_interface.py b/plac/doc/sql_interface.py
index d045d03..ccedb97 100644
--- a/plac/doc/sql_interface.py
+++ b/plac/doc/sql_interface.py
@@ -11,8 +11,8 @@ class SqlInterface(object):
commands = ['SELECT']
def __init__(self, dsn):
self.soup = SqlSoup(dsn)
- def SELECT(self, *args):
- sql = 'SELECT ' + ' '.join(args)
+ def SELECT(self, argstring):
+ sql = 'SELECT ' + argstring
for row in self.soup.bind.execute(sql):
yield str(row) # the formatting can be much improved
@@ -21,5 +21,10 @@ rl_input = plac.ReadlineInput(
histfile=os.path.expanduser('~/.sql_interface.history'),
case_sensitive=False)
+def split_on_first_space(line, commentchar):
+ return line.strip().split(' ', 1) # ignoring comments
+
if __name__ == '__main__':
- plac.Interpreter(plac.call(SqlInterface)).interact(rl_input)
+ si = plac.call(SqlInterface)
+ i = plac.Interpreter(si, split=split_on_first_space)
+ i.interact(rl_input)
diff --git a/plac/plac_ext.py b/plac/plac_ext.py
index 43adbbb..3cb858d 100644
--- a/plac/plac_ext.py
+++ b/plac/plac_ext.py
@@ -491,13 +491,14 @@ class Interpreter(object):
A context manager with a .send method and a few utility methods:
execute, test and doctest.
"""
- def __init__(self, obj, commentchar='#'):
+ def __init__(self, obj, commentchar='#', split=shlex.split):
self.obj = obj
try:
self.name = obj.__module__
except AttributeError:
self.name = 'plac'
self.commentchar = commentchar
+ self.split = split
self._set_commands(obj)
self.tm = TaskManager(obj)
self.parser = plac_core.parser_from(obj, prog='', add_help=False)
@@ -544,7 +545,7 @@ class Interpreter(object):
raise RuntimeError(_('%r not initialized: probably you forgot to '
'use the with statement') % self)
if isinstance(line, basestring):
- arglist = shlex.split(line, self.commentchar)
+ arglist = self.split(line, self.commentchar)
else: # expects a list of strings
arglist = line
return self._interpreter.send(arglist)
@@ -653,10 +654,8 @@ class Interpreter(object):
consolle. Using rlwrap is recommended.
"""
if stdin is sys.stdin and readline: # use readline
- # print '.%s.history' % self.name
- stdin = ReadlineInput(
- self.commands, prompt, histfile='.%s.history' % self.name,
- case_sensitive=True)
+ histfile = os.path.expanduser('~/.%s.history' % self.name)
+ stdin = ReadlineInput(self.commands, prompt, histfile=histfile)
self.stdin = stdin
self.prompt = getattr(stdin, 'prompt', prompt)
self.verbose = verbose
diff --git a/plac/plac_runner.py b/plac/plac_runner.py
new file mode 100644
index 0000000..c9b7cef
--- /dev/null
+++ b/plac/plac_runner.py
@@ -0,0 +1,58 @@
+#!python
+from __future__ import with_statement
+import os, sys, shlex, inspect
+import plac
+
+def run(fnames, cmd, verbose):
+ "Run batch scripts and tests"
+ for fname in fnames:
+ with open(fname) as f:
+ lines = list(f)
+ if not lines[0].startswith('#!'):
+ sys.exit('Missing or incorrect shebang line!')
+ firstline = lines[0][2:] # strip the shebang
+ init_args = shlex.split(firstline)
+ tool = plac.import_main(*init_args)
+ command = getattr(plac.Interpreter(tool), cmd) # doctest or execute
+ if verbose:
+ sys.stdout.write('Running %s with %s' % (fname, firstline))
+ command(lines[1:], verbose=verbose)
+
+@plac.annotations(
+ verbose=('verbose mode', 'flag', 'v'),
+ interactive=('run plac tool in interactive mode', 'flag', 'i'),
+ batch=('run plac batch files', 'flag', 'b'),
+ test=('run plac test files', 'flag', 't'),
+ fname='script to run (.py or .plac or .placet)',
+ extra='additional arguments',
+ )
+def main(verbose, interactive, batch, test, fname=None, *extra):
+ "Runner for plac tools, plac batch files and plac tests"
+ baseparser = plac.parser_from(main)
+ if fname is None:
+ baseparser.print_help()
+ elif sys.argv[1] == fname: # script mode
+ plactool = plac.import_main(
+ fname, prog=os.path.basename(sys.argv[0]) + ' ' + fname)
+ out = plac.call(plactool, sys.argv[2:], eager=False)
+ if plac.iterable(out):
+ for output in out:
+ print(output)
+ else:
+ print(out)
+ elif interactive:
+ plactool = plac.import_main(fname, *extra, **{'prog': ''})
+ if inspect.isclass(plactool): # special case
+ plactool = plactool()
+ plac.Interpreter(plactool).interact(verbose=verbose)
+ elif batch:
+ run((fname,) + extra, 'execute', verbose)
+ elif test:
+ run((fname,) + extra, 'doctest', verbose)
+ print('run %s plac test(s)' % (len(extra) + 1))
+ else:
+ baseparser.print_usage()
+main.add_help = False
+
+if __name__ == '__main__':
+ plac.call(main)