{"id":17800443,"url":"https://github.com/anntzer/parsedcmd","last_synced_at":"2025-03-17T08:38:14.585Z","repository":{"id":2762645,"uuid":"3760814","full_name":"anntzer/parsedcmd","owner":"anntzer","description":"Python's Cmd class enhanced with argument line parsing","archived":false,"fork":false,"pushed_at":"2012-09-13T00:57:45.000Z","size":112,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T23:29:03.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anntzer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-03-19T05:05:13.000Z","updated_at":"2018-03-25T12:48:51.000Z","dependencies_parsed_at":"2022-09-08T05:51:26.715Z","dependency_job_id":null,"html_url":"https://github.com/anntzer/parsedcmd","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anntzer%2Fparsedcmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anntzer%2Fparsedcmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anntzer%2Fparsedcmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anntzer%2Fparsedcmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anntzer","download_url":"https://codeload.github.com/anntzer/parsedcmd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243858656,"owners_count":20359392,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-27T12:21:59.432Z","updated_at":"2025-03-17T08:38:14.167Z","avatar_url":"https://github.com/anntzer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"ParsedCmd - A Cmd with argument list parsing\n============================================\n\nParsedCmd is an extension built around the excellent cmd module of the standard\nlibrary.  Cmd allows one to build simple custom shells using `do_*` methods,\ntaking care in particular of the REPL loop and the interactive help.  However,\nno facility is given for parsing the argument line (`do_*` methods are passed\nthe rest of the line as a single string argument).\n\nWith ParsedCmd, `do_*` methods can be type-annotated, either using Python\n3's function annotation syntax, or with the ad-hoc `annotate` decorator,\nallowing the dispatcher to parse the argument list for them.  Arguments can\nalso be marked as keyword-only, either using Python 3's dedicated syntax, or\nwith the ad-hoc `kw_only` decorator, in which case they will be assigned only\nif given as explicit arguments, i.e. `method -option opt` translates into\n`do_method(option=opt)` if `option` is keyword-only.\n\nThese annotations can also used to enhance the output of the default `do_help`\nmethod, by setting the `show_usage` attribute of the ParsedCmd object to True.\n\nExample (Python 2.6-2.7)\n========================\n\n    from parsedcmd import *\n\n    class UI(ParsedCmd):\n        # Non-annotated arguments default to str.\n        # boolean is a utility function, that casts every string to True,\n        # except \"f\", \"false\", \"off\" and \"0\" (case-insensitive).\n        @annotate(flag=boolean, repeat=int)\n        @kw_only(\"flag\", \"repeat\")\n        def do_print(self, line=\"abc\", flag=True, repeat=1):\n            \"\"\"Print a given string (defaults to \"abc\").\n            Print nothing if -flag is set to false.\n            Print multiple copies if -repeat N option is given.\n            \"\"\"\n            if flag:\n                for i in range(repeat):\n                    print(line, file=self.stdout)\n\n        # *args can also be annotated.\n        # Python 2's usual limitations about mixing keyword arguments and *args\n        # applies.\n        @annotate(mul=int, nums=int)\n        def do_multiply(self, mul, *nums):\n            \"\"\"Print `mul` times the numbers given.\n            \"\"\"\n            for num in nums:\n                print(mul * num, file=self.stdout)\n\n        # Do not parse the argument line for do_shell.\n        @gets_raw\n        def do_shell(self, line):\n            \"\"\"Evaluates the given line.\n            \"\"\"\n            eval(line)\n\nExample (Python 3)\n==================\n\n    from parsedcmd import *\n\n    class UI(ParsedCmd):\n        def do_print(self, line=\"abc\", *, flag: boolean=True, repeat: int=1):\n            \"\"\"Print a given string (defaults to \"abc\").\n            Print nothing if -flag is set to false.\n            Print multiple copies if -repeat N option is given.\n            \"\"\"\n            if flag:\n                for i in range(repeat):\n                    print(line, file=self.stdout)\n\n        def do_multiply(self, mul: int, *nums: int):\n            \"\"\"Print `mul` times the numbers given.\n            \"\"\"\n            for num in nums:\n                print(mul * num, file=self.stdout)\n\n        @gets_raw\n        def do_shell(self, line):\n            \"\"\"Evaluates the given line.\n            \"\"\"\n            eval(line)\n\nRemarks\n=======\n\nThe parsing is done in the following steps:\n  - the input line is passed to the `split()` method (by default\n    `shlex.split()`), and the result is bound to the argument list of the\n    `do_*` method.\n  - initial options (`-opt val`) are assigned to keyword-only arguments (which\n    can be simulated in Python 2 using the `@kw_only` decorator).\n  - each value bound to an argument annotated with a callable, either through\n    `@annotate([arg=callable]*)`, or through Python 3's function annotation\n    syntax (`f(arg[=default]: callable)`), is passed to it; however, this does\n    not affect default values),\n  - if `do_*` has an annotated `*args` argument, then each element\n    of args / each value in kwargs is casted.\n  - in theory, `**kwargs` are also parsed and cast but there is currently\n    effectively no way to assign to them.\n\nParsedCmd interacts imperfectly with decorated functions.  Currently, it\nfollows the `__wrapped__` attribute until finding a function that either\ndoesn't have this attribute or is decorated with `@use_my_annotations`, uses\nthe signature and the annotations of this function to create the argument\nlist, which is then passed to the wrapper function.  In particular, ParsedCmd\nprovides a `wraps` function that works like the one provided in functools, but\nalso sets the `__wrapped__` attribute (as in Python 3.3 or higher).\n\nTesting\n=======\n\nJust run `py.test` in the source folder.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanntzer%2Fparsedcmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanntzer%2Fparsedcmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanntzer%2Fparsedcmd/lists"}