go-flag


Namego-flag JSON
Version 2.0.1 PyPI version JSON
download
home_pageNone
SummaryA port of Go's flag package to Python
upload_time2024-11-22 22:05:09
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseBSD-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"
}
        
Elapsed time: 0.50171s