summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2010-05-28 17:56:13 +0200
committerMichele Simionato <michele.simionato@gmail.com>2010-05-28 17:56:13 +0200
commit224d123f0243fd22dbe3c76bd1a7c4716be2e986 (patch)
treebecae9792af1cbc408e2cbcf391473797f2407a5
parent745a1ff1859bd31b48dc13c0adddadcc6ca0228b (diff)
downloadmicheles-224d123f0243fd22dbe3c76bd1a7c4716be2e986.tar.gz
Renamed optionparser to clap and added a much smarter interface
-rw-r--r--clap/calc.py15
-rw-r--r--clap/clap.py (renamed from optionparser/optionparser.py)47
-rw-r--r--clap/doc.html (renamed from optionparser/doc.html)18
-rw-r--r--clap/doc.txt (renamed from optionparser/doc.txt)12
-rw-r--r--clap/example.py (renamed from optionparser/example.py)2
-rw-r--r--clap/example.txt (renamed from optionparser/example.txt)0
-rw-r--r--clap/example2.py20
-rw-r--r--clap/test_clap.py (renamed from optionparser/test_optionparser.py)2
-rw-r--r--decorator/src/decorator.py2
9 files changed, 85 insertions, 33 deletions
diff --git a/clap/calc.py b/clap/calc.py
new file mode 100644
index 0000000..8d761cd
--- /dev/null
+++ b/clap/calc.py
@@ -0,0 +1,15 @@
+import operator
+
+def calc(op, numbers):
+ """
+ usage: %prog op numbers ... where op can be sum or mul
+ """
+ if op == 'sum':
+ print sum(map(float, numbers))
+ elif op == 'mul':
+ print reduce(operator.__mul__, map(float, numbers), 1)
+ else:
+ raise ValueError('Invalid operator %r' % op)
+
+if __name__ == '__main__':
+ import clap; clap.call(calc)
diff --git a/optionparser/optionparser.py b/clap/clap.py
index d3958de..8f2f76d 100644
--- a/optionparser/optionparser.py
+++ b/clap/clap.py
@@ -24,7 +24,8 @@
## DAMAGE.
"""
-See optionparser/doc.html for the documentation.
+CLAP, the smart and simple Command Line Arguments Parser.
+See clap/doc.html for the documentation.
"""
import optparse, re, sys, string
@@ -94,19 +95,22 @@ def make_get_default_values(defaults):
dict(__nonzero__=__nonzero__))
return lambda : Values(defaults)
+optionstring = None # singleton
+
class OptionParser(object):
"""
There should be only one instance of it.
Attributes: all_options, expected_args, rest_arg, p
"""
- def __init__(self, optionstring):
+ def __init__(self, doc):
"Populate the option parser."
- assert optionstring is not None, \
+ global optionstring
+ assert doc is not None, \
"Missing usage string (maybe __doc__ is None)"
- self.__class__.optionstring = optionstring
+ optionstring = doc.replace('%prog', sys.argv[0])
- # parse the optionstring
- match = rx.usage.search(optionstring)
+ # parse the doc
+ match = rx.usage.search(doc)
if not match:
raise ParsingError("Could not find the option definitions")
optlines = match.group("lines").splitlines()
@@ -170,12 +174,25 @@ class OptionParser(object):
@classmethod
def exit(cls, msg=None):
- if msg is None:
- msg = cls.optionstring.replace("%prog", sys.argv[0])
- raise SystemExit(msg)
-
-if __name__ == '__main__':
- arg = OptionParser('''\
-usage: %prog args ... [options]
--d, --delete=: delete a file
-''').parse_args(['-d', 'foo', 'arg1', 'arg2'])
+ exit(msg)
+
+def call(func, args=None, doc=None):
+ """
+ Magically calls func by passing to it the command lines arguments,
+ parsed according to the docstring of func.
+ """
+ if args is None:
+ args = sys.argv[1:]
+ if doc is None:
+ doc = func.__doc__
+ try:
+ arg = OptionParser(doc).parse_args(args)
+ except ParsingError, e:
+ print 'ParsingError:', e
+ OptionParser.exit()
+ return func(**vars(arg))
+
+def exit(msg=None):
+ if msg is None:
+ msg = optionstring
+ raise SystemExit(msg)
diff --git a/optionparser/doc.html b/clap/doc.html
index 8361c4c..15a033d 100644
--- a/optionparser/doc.html
+++ b/clap/doc.html
@@ -4,7 +4,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
-<title>optionparser: a simplified interface to optparse</title>
+<title>clap: a simplified interface to optparse</title>
<style type="text/css">
.highlight { background: #f8f8f8; }
@@ -71,8 +71,8 @@
</style>
</head>
<body>
-<div class="document" id="optionparser-a-simplified-interface-to-optparse">
-<h1 class="title">optionparser: a simplified interface to optparse</h1>
+<div class="document" id="clap-a-simplified-interface-to-optparse">
+<h1 class="title">clap: a simplified interface to optparse</h1>
<p>The Python standard library contains three different modules for the
parsing of command line options: <tt class="docutils literal">getopt</tt> (from the stone age),
@@ -91,18 +91,18 @@ not interested in features, they just want to be able to write a simple
command line tool from a simple specification, not to build a command line
parser by hand. Unfortunately, the current modules in the standard
library forces them to go the hard way.</p>
-<p><tt class="docutils literal">optionparser</tt> solves this problem. By design it is not intended to
+<p><tt class="docutils literal">clap</tt> solves this problem. By design it is not intended to
be an industrial strength command line parsing module. Its capabilities
are limited <em>on purpose</em>. If you need more power, by all means use the
parsing modules in the standard library. Still, I have been using Python for 8
years and never once I had to use the full power of <tt class="docutils literal">optparse</tt>: the
-features provided by <tt class="docutils literal">optionparser</tt> have been more than enough for
+features provided by <tt class="docutils literal">clap</tt> have been more than enough for
me and I guess that the same could be said for most people.</p>
-<p>The fundamental idea behind <tt class="docutils literal">optionparser</tt> is to extract the parser
+<p>The fundamental idea behind <tt class="docutils literal">clap</tt> is to extract the parser
from the usage docstring. In this way the user does not need to write
the parser by hand by duplicating the instructions which she has already
encoded implicitly in the usage docstring.</p>
-<p>Here is a concrete example of a script using <tt class="docutils literal">optionparser</tt>:</p>
+<p>Here is a concrete example of a script using <tt class="docutils literal">clap</tt>:</p>
<pre class="literal-block">
&quot;&quot;&quot;\
usage: %prog [options]
@@ -116,7 +116,7 @@ def print_(color, txt):
print '\x1b[%dm%s\x1b[0m' % (code, txt)
if __name__=='__main__':
- from optionparser import OptionParser
+ from clap import OptionParser
option, args = OptionParser(__doc__).parse_args()
color = option.color
if option.delete_all:
@@ -157,7 +157,7 @@ Delete all files # this is printed in red on most terminals
</pre>
-<p>Here is some explanation. First of all, <tt class="docutils literal">optionparser</tt> recognizes
+<p>Here is some explanation. First of all, <tt class="docutils literal">clap</tt> recognizes
four classes of command line arguments:</p>
<ul class="simple">
<li>positional arguments (none in this example)</li>
diff --git a/optionparser/doc.txt b/clap/doc.txt
index ea8dbce..84d254a 100644
--- a/optionparser/doc.txt
+++ b/clap/doc.txt
@@ -1,4 +1,4 @@
-optionparser: a simplified interface to optparse
+clap: a simplified interface to optparse
-------------------------------------------------
The Python standard library contains three different modules for the
@@ -20,20 +20,20 @@ command line tool from a simple specification, not to build a command line
parser by hand. Unfortunately, the current modules in the standard
library forces them to go the hard way.
-``optionparser`` solves this problem. By design it is not intended to
+``clap`` solves this problem. By design it is not intended to
be an industrial strength command line parsing module. Its capabilities
are limited *on purpose*. If you need more power, by all means use the
parsing modules in the standard library. Still, I have been using Python for 8
years and never once I had to use the full power of ``optparse``: the
-features provided by ``optionparser`` have been more than enough for
+features provided by ``clap`` have been more than enough for
me and I guess that the same could be said for most people.
-The fundamental idea behind ``optionparser`` is to extract the parser
+The fundamental idea behind ``clap`` is to extract the parser
from the usage docstring. In this way the user does not need to write
the parser by hand by duplicating the instructions which she has already
encoded implicitly in the usage docstring.
-Here is a concrete example of a script using ``optionparser``:
+Here is a concrete example of a script using ``clap``:
.. include:: example.py
:literal:
@@ -43,7 +43,7 @@ Here are a few examples of usage:
.. include:: example.txt
:literal:
-Here are some explanations. First of all, ``optionparser`` recognizes
+Here are some explanations. First of all, ``clap`` recognizes
four classes of command line arguments:
- positional arguments (none in this example)
diff --git a/optionparser/example.py b/clap/example.py
index 882aa8e..ce813e0 100644
--- a/optionparser/example.py
+++ b/clap/example.py
@@ -4,7 +4,7 @@ usage: %prog [options]
-d, --delete=: delete the given file
-a, --delete-all: delete all files
"""
-from optionparser import OptionParser
+from clap import OptionParser
def print_(color, txt):
code = {'black': 30, 'red': 31}[color]
diff --git a/optionparser/example.txt b/clap/example.txt
index 4cf83ff..4cf83ff 100644
--- a/optionparser/example.txt
+++ b/clap/example.txt
diff --git a/clap/example2.py b/clap/example2.py
new file mode 100644
index 0000000..842d9a9
--- /dev/null
+++ b/clap/example2.py
@@ -0,0 +1,20 @@
+def print_(color, txt):
+ code = {'black': 30, 'red': 31}[color]
+ print '\x1b[%dm%s\x1b[0m' % (code, txt)
+
+def main(delete, delete_all, color):
+ """usage: %prog
+ -c, --color=black: set default color
+ -d, --delete=: delete the given file
+ -a, --delete-all: delete all files
+ """
+ if delete_all:
+ print_(option.color, "Delete all files")
+ elif delete:
+ print_(option.color, "Delete the file %s" % option.delete)
+ else:
+ clap.exit()
+
+if __name__=='__main__':
+ import clap; clap.call(main)
+
diff --git a/optionparser/test_optionparser.py b/clap/test_clap.py
index 9b34610..b8efbe9 100644
--- a/optionparser/test_optionparser.py
+++ b/clap/test_clap.py
@@ -1,5 +1,5 @@
import sys
-from optionparser import OptionParser, ParsingError
+from clap import OptionParser, ParsingError
def expect_error(err, func, *args, **kw):
"""
diff --git a/decorator/src/decorator.py b/decorator/src/decorator.py
index 2e6d128..a005230 100644
--- a/decorator/src/decorator.py
+++ b/decorator/src/decorator.py
@@ -1,6 +1,6 @@
########################## LICENCE ###############################
##
-## Copyright (c) 2005, Michele Simionato
+## Copyright (c) 2005-2010, Michele Simionato
## All rights reserved.
##
## Redistributions of source code must retain the above copyright