Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/anntzer/parsedcmd
Python's Cmd class enhanced with argument line parsing
https://github.com/anntzer/parsedcmd
Last synced: about 2 months ago
JSON representation
Python's Cmd class enhanced with argument line parsing
- Host: GitHub
- URL: https://github.com/anntzer/parsedcmd
- Owner: anntzer
- License: other
- Created: 2012-03-19T05:05:13.000Z (almost 13 years ago)
- Default Branch: master
- Last Pushed: 2012-09-13T00:57:45.000Z (over 12 years ago)
- Last Synced: 2023-03-23T00:43:59.384Z (almost 2 years ago)
- Language: Python
- Homepage:
- Size: 109 KB
- Stars: 7
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
ParsedCmd - A Cmd with argument list parsing
============================================ParsedCmd is an extension built around the excellent cmd module of the standard
library. Cmd allows one to build simple custom shells using `do_*` methods,
taking care in particular of the REPL loop and the interactive help. However,
no facility is given for parsing the argument line (`do_*` methods are passed
the rest of the line as a single string argument).With ParsedCmd, `do_*` methods can be type-annotated, either using Python
3's function annotation syntax, or with the ad-hoc `annotate` decorator,
allowing the dispatcher to parse the argument list for them. Arguments can
also be marked as keyword-only, either using Python 3's dedicated syntax, or
with the ad-hoc `kw_only` decorator, in which case they will be assigned only
if given as explicit arguments, i.e. `method -option opt` translates into
`do_method(option=opt)` if `option` is keyword-only.These annotations can also used to enhance the output of the default `do_help`
method, by setting the `show_usage` attribute of the ParsedCmd object to True.Example (Python 2.6-2.7)
========================from parsedcmd import *
class UI(ParsedCmd):
# Non-annotated arguments default to str.
# boolean is a utility function, that casts every string to True,
# except "f", "false", "off" and "0" (case-insensitive).
@annotate(flag=boolean, repeat=int)
@kw_only("flag", "repeat")
def do_print(self, line="abc", flag=True, repeat=1):
"""Print a given string (defaults to "abc").
Print nothing if -flag is set to false.
Print multiple copies if -repeat N option is given.
"""
if flag:
for i in range(repeat):
print(line, file=self.stdout)# *args can also be annotated.
# Python 2's usual limitations about mixing keyword arguments and *args
# applies.
@annotate(mul=int, nums=int)
def do_multiply(self, mul, *nums):
"""Print `mul` times the numbers given.
"""
for num in nums:
print(mul * num, file=self.stdout)# Do not parse the argument line for do_shell.
@gets_raw
def do_shell(self, line):
"""Evaluates the given line.
"""
eval(line)Example (Python 3)
==================from parsedcmd import *
class UI(ParsedCmd):
def do_print(self, line="abc", *, flag: boolean=True, repeat: int=1):
"""Print a given string (defaults to "abc").
Print nothing if -flag is set to false.
Print multiple copies if -repeat N option is given.
"""
if flag:
for i in range(repeat):
print(line, file=self.stdout)def do_multiply(self, mul: int, *nums: int):
"""Print `mul` times the numbers given.
"""
for num in nums:
print(mul * num, file=self.stdout)@gets_raw
def do_shell(self, line):
"""Evaluates the given line.
"""
eval(line)Remarks
=======The parsing is done in the following steps:
- the input line is passed to the `split()` method (by default
`shlex.split()`), and the result is bound to the argument list of the
`do_*` method.
- initial options (`-opt val`) are assigned to keyword-only arguments (which
can be simulated in Python 2 using the `@kw_only` decorator).
- each value bound to an argument annotated with a callable, either through
`@annotate([arg=callable]*)`, or through Python 3's function annotation
syntax (`f(arg[=default]: callable)`), is passed to it; however, this does
not affect default values),
- if `do_*` has an annotated `*args` argument, then each element
of args / each value in kwargs is casted.
- in theory, `**kwargs` are also parsed and cast but there is currently
effectively no way to assign to them.ParsedCmd interacts imperfectly with decorated functions. Currently, it
follows the `__wrapped__` attribute until finding a function that either
doesn't have this attribute or is decorated with `@use_my_annotations`, uses
the signature and the annotations of this function to create the argument
list, which is then passed to the wrapper function. In particular, ParsedCmd
provides a `wraps` function that works like the one provided in functools, but
also sets the `__wrapped__` attribute (as in Python 3.3 or higher).Testing
=======Just run `py.test` in the source folder.