Name | go-flag JSON |
Version |
2.0.1
JSON |
| download |
home_page | None |
Summary | A port of Go's flag package to Python |
upload_time | 2024-11-22 22:05:09 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.12 |
license | BSD-3 |
keywords |
go
golang
flag
options
cli
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# go-flag
go-flag is a port of [Go's flag package](https://pkg.go.dev/flag) to Python.
## Why??
Typically, [click](https://click.palletsprojects.com/en/stable/) or
[argparse](https://docs.python.org/3/library/argparse.html) are going to be
more straightforward than using this library. But there are a few motivations
for using go-flag:
1. You want to write a tool in Python, which behaves like a Go program. If
you are using it alongside other programs that use Go-style flags, it can
make your tool feel more at home in that ecosystem.
2. You're a Gopher, and want to write some Python. In that case, this library
may feel more comfortable.
3. You are porting a Go program. This library can help minimize the amount of
effort involved in translating idioms.
Also, I think this is funny.
## Usage
The simplest usage of this library involves defining some flags and running
a parse:
```py
#!/usr/bin/env python
import flag
force = flag.bool_("force", False, "force the command to execute")
count = flag.int_("count", 1, "a count")
name = flag.string("name", "Josh", "a name")
threshold = flag.float_("threshold", 1.0, "a threshold")
flag.parse()
print(dict(
force=force.deref(),
count=count.deref(),
name=name.deref(),
threshold=threshold.deref()
))
```
With no arguments, this will print:
```
$ python examples/simple.py
{'force': False, 'count': 1, 'name': 'Josh', 'threshold': 1.0}
```
With a number of argument, we see:
```
$ python examples/simple.py -count 3 -force=true -name KB -threshold 0.5
{'force': True, 'count': 3, 'name': 'KB', 'threshold': 0.5}
```
With the help flag, this will print:
```
$ python examples/simple.py -h
Usage of examples/simple.py:
-count int
a count (default 1)
-force
force the command to execute
-name string
a name (default Josh)
-threshold float
a threshold (default 1)
```
In this usage, these flags are instances of `flag.Ptr`. But you may want to
be a little more fancy - for instance, using a class and `flag.AttrRef`:
```py
#!/usr/bin/env python
import flag
class Config:
force: bool = flag.zero.bool_
count: int = flag.zero.int_
name: str = flag.zero.string
threshold: float = flag.zero.float_
force = flag.AttrRef(Config, "force")
count = flag.AttrRef(Config, "count")
name = flag.AttrRef(Config, "name")
threshold = flag.AttrRef(Config, "threshold")
flag.bool_var(force, "force", False, "force the command to execute")
flag.int_var(count, "count", 1, "a count")
flag.string_var(name, "name", "Josh", "a name")
flag.float_var(threshold, "threshold", 1.0, "a threshold")
flag.parse()
print(
dict(
force=Config.force,
count=Config.count,
name=Config.name,
threshold=Config.threshold,
)
)
```
This outputs:
```
$ python examples/class.py -count 3 -force=true -name KB -threshold 0.5
{'force': True, 'count': 3, 'name': 'KB', 'threshold': 0.5}
```
The `flag.KeyRef` class can implement a similar pattern with dicts.
In general, aside from the need to use classes that fake pointers and a number
of data types not applicable to Python, the API should follow the same general
shape as Go's flag package. For more documentation, read the source - the
docstrings should be *relatively* complete.
## Error Handling
We already saw one strange set of abstractions we needed to pretend to be
Go - the `Pointer` protocol and its implementations. The other way in which
this library emulates Go is in its error handling.
Not to worry - this library raises Exceptions like God intended. But it *does*
have two non-overlapping classes of errors: `flag.Error` and `flag.Panic`. The
former emulates cases where Go would have us return an `error`. The latter is
raised when emulating a Go panic.
While the internal details of how `Error`s are created are unusual, the end
result is very simple error classes. In general, you can except on `flag.Error`
and allow raised instances of `flag.Panic` to crash the program. But if you
wish to have more fine-grained control, you may with to except `flag.Panic` as
well.
## Development
I developed this project using [uv](https://docs.astral.sh/uv/). It is a little
immature, and I honestly can't recommend it yet for production use. We will
see if I stick with this stack over time.
Nevertheless, the `justfile` should contain most of what you need - including
`just format`, `just lint`, `just check`, and `just test`. Note that type
checking requires node.js, because I use pyright.
## License
I licensed this under a BSD-3 license, in an attempt to stay compatible with
Go's license.
Raw data
{
"_id": null,
"home_page": null,
"name": "go-flag",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "go, golang, flag, options, cli",
"author": null,
"author_email": "Josh Holbrook <josh.holbrook@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/58/fe/177da4854866e2eaa635d38b666041e4e53be1492c5930295dc63873dd3f/go_flag-2.0.1.tar.gz",
"platform": null,
"description": "# go-flag\n\ngo-flag is a port of [Go's flag package](https://pkg.go.dev/flag) to Python.\n\n## Why??\n\nTypically, [click](https://click.palletsprojects.com/en/stable/) or\n[argparse](https://docs.python.org/3/library/argparse.html) are going to be\nmore straightforward than using this library. But there are a few motivations\nfor using go-flag:\n\n1. You want to write a tool in Python, which behaves like a Go program. If\n you are using it alongside other programs that use Go-style flags, it can\n make your tool feel more at home in that ecosystem.\n2. You're a Gopher, and want to write some Python. In that case, this library\n may feel more comfortable.\n3. You are porting a Go program. This library can help minimize the amount of\n effort involved in translating idioms.\n\nAlso, I think this is funny.\n\n## Usage\n\nThe simplest usage of this library involves defining some flags and running\na parse:\n\n```py\n#!/usr/bin/env python\n\nimport flag\n\nforce = flag.bool_(\"force\", False, \"force the command to execute\")\ncount = flag.int_(\"count\", 1, \"a count\")\nname = flag.string(\"name\", \"Josh\", \"a name\")\nthreshold = flag.float_(\"threshold\", 1.0, \"a threshold\")\n\nflag.parse()\n\nprint(dict(\n force=force.deref(),\n count=count.deref(),\n name=name.deref(),\n threshold=threshold.deref()\n))\n```\n\nWith no arguments, this will print:\n\n```\n$ python examples/simple.py\n{'force': False, 'count': 1, 'name': 'Josh', 'threshold': 1.0}\n```\n\nWith a number of argument, we see:\n\n```\n$ python examples/simple.py -count 3 -force=true -name KB -threshold 0.5\n{'force': True, 'count': 3, 'name': 'KB', 'threshold': 0.5}\n```\n\nWith the help flag, this will print:\n\n```\n$ python examples/simple.py -h\nUsage of examples/simple.py:\n\n -count int\n \ta count (default 1)\n -force\n \tforce the command to execute\n -name string\n \ta name (default Josh)\n -threshold float\n \ta threshold (default 1)\n```\n\nIn this usage, these flags are instances of `flag.Ptr`. But you may want to\nbe a little more fancy - for instance, using a class and `flag.AttrRef`:\n\n```py\n#!/usr/bin/env python\n\nimport flag\n\n\nclass Config:\n force: bool = flag.zero.bool_\n count: int = flag.zero.int_\n name: str = flag.zero.string\n threshold: float = flag.zero.float_\n\n\nforce = flag.AttrRef(Config, \"force\")\ncount = flag.AttrRef(Config, \"count\")\nname = flag.AttrRef(Config, \"name\")\nthreshold = flag.AttrRef(Config, \"threshold\")\n\nflag.bool_var(force, \"force\", False, \"force the command to execute\")\nflag.int_var(count, \"count\", 1, \"a count\")\nflag.string_var(name, \"name\", \"Josh\", \"a name\")\nflag.float_var(threshold, \"threshold\", 1.0, \"a threshold\")\n\nflag.parse()\n\nprint(\n dict(\n force=Config.force,\n count=Config.count,\n name=Config.name,\n threshold=Config.threshold,\n )\n)\n```\n\nThis outputs:\n\n```\n$ python examples/class.py -count 3 -force=true -name KB -threshold 0.5\n{'force': True, 'count': 3, 'name': 'KB', 'threshold': 0.5}\n```\n\nThe `flag.KeyRef` class can implement a similar pattern with dicts.\n\nIn general, aside from the need to use classes that fake pointers and a number\nof data types not applicable to Python, the API should follow the same general\nshape as Go's flag package. For more documentation, read the source - the\ndocstrings should be *relatively* complete.\n\n## Error Handling\n\nWe already saw one strange set of abstractions we needed to pretend to be\nGo - the `Pointer` protocol and its implementations. The other way in which\nthis library emulates Go is in its error handling.\n\nNot to worry - this library raises Exceptions like God intended. But it *does*\nhave two non-overlapping classes of errors: `flag.Error` and `flag.Panic`. The\nformer emulates cases where Go would have us return an `error`. The latter is\nraised when emulating a Go panic.\n\nWhile the internal details of how `Error`s are created are unusual, the end\nresult is very simple error classes. In general, you can except on `flag.Error`\nand allow raised instances of `flag.Panic` to crash the program. But if you\nwish to have more fine-grained control, you may with to except `flag.Panic` as\nwell.\n\n## Development\n\nI developed this project using [uv](https://docs.astral.sh/uv/). It is a little\nimmature, and I honestly can't recommend it yet for production use. We will\nsee if I stick with this stack over time.\n\nNevertheless, the `justfile` should contain most of what you need - including\n`just format`, `just lint`, `just check`, and `just test`. Note that type\nchecking requires node.js, because I use pyright.\n\n## License\n\nI licensed this under a BSD-3 license, in an attempt to stay compatible with\nGo's license.\n",
"bugtrack_url": null,
"license": "BSD-3",
"summary": "A port of Go's flag package to Python",
"version": "2.0.1",
"project_urls": {
"Repository": "https://github.com/jfhbrook/go-flag"
},
"split_keywords": [
"go",
" golang",
" flag",
" options",
" cli"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "f4532e2a4bca6665bc4c5f5d9eec5e32ebeb8ee4a39fb98112e4263ea3049b15",
"md5": "d7ed19a7b78a84be11c68ed1fcd8ff07",
"sha256": "cea4d6618775cb10da1beb08dc4a6822cdfca122b0d980aadd10405eb3573472"
},
"downloads": -1,
"filename": "go_flag-2.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d7ed19a7b78a84be11c68ed1fcd8ff07",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 19139,
"upload_time": "2024-11-22T22:05:07",
"upload_time_iso_8601": "2024-11-22T22:05:07.375253Z",
"url": "https://files.pythonhosted.org/packages/f4/53/2e2a4bca6665bc4c5f5d9eec5e32ebeb8ee4a39fb98112e4263ea3049b15/go_flag-2.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "58fe177da4854866e2eaa635d38b666041e4e53be1492c5930295dc63873dd3f",
"md5": "9ad09579baa200f48c98d2bfef914f84",
"sha256": "f829fc72785ac1f93573c10953a29926b5106a0ac73239b0177f4917891881b4"
},
"downloads": -1,
"filename": "go_flag-2.0.1.tar.gz",
"has_sig": false,
"md5_digest": "9ad09579baa200f48c98d2bfef914f84",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 22360,
"upload_time": "2024-11-22T22:05:09",
"upload_time_iso_8601": "2024-11-22T22:05:09.234504Z",
"url": "https://files.pythonhosted.org/packages/58/fe/177da4854866e2eaa635d38b666041e4e53be1492c5930295dc63873dd3f/go_flag-2.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-22 22:05:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jfhbrook",
"github_project": "go-flag",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "go-flag"
}