# More KWARGS!
Object destructuring of function parameters for Python!
[](https://pypi.org/project/mo-kwargs/)
[](https://github.com/klahnakoski/mo-kwargs/actions/workflows/build.yml)
[](https://coveralls.io/github/klahnakoski/mo-kwargs?branch=dev)
[](https://pepy.tech/project/mo-kwargs)
## Motivation
Javascript has [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring), and it can be used for function parameters. This has a couple of benefts over Python's keyword arguments:
* Extra caller parameters are ignored (eg `f({a, b, c})`)
* Duplicate parameters are handled elegantly (eg `f({a, a})`)
The `mo-kwargs` library provides this functionality with the `@override` decorator, with additional benefits:
* required parameters throw an error if missing, just like regular Python
* all parameters, even ones not in the argument list, are passed in the optional `kwargs` parameter
The `@override` decorator adds a `kwargs` argument which can be passed a dict of call parameters; but unlike `**kwargs`, it will not raise duplicate key exceptions.
## Provide default values
We decorate the `login()` function with `@override`. `username` is a required parameter, and `password` will default to `None`.
@override
def login(username, password=None):
pass
Define some `dicts` for use with our `kwargs` parameter:
creds = {"userame": "ekyle", "password": "password123"}
alt_creds = {"username": "klahnakoski"}
The simplest case is when we use `kwargs` with no overrides
login(kwargs=creds)
# SAME AS
login(**creds)
# SAME AS
login(username="ekyle", password="password123")
You may override any property in `kwargs`: In this case it is `password`
login(password="123", kwargs=creds)
# SAME AS
login(username="ekyle", password="123")
There is no problem with overriding everything in `kwargs`:
login(username="klahnakoski", password="asd213", kwargs=creds)
# SAME AS
login(username="klahnakoski", password="asd213")
You may continue to use `**kwargs`; which provides a way to overlay one parameter template (`creds`) with another (`alt_creds`)
login(kwargs=creds, **alt_creds)
# SAME AS
login(username="klahnakoski", password="password123")
## Handle too many parameters
Sometimes your method parameters come from a configuration file, or some other outside source which is outside your control. There may be more parameters than your method is willing to accept.
creds = {"username": "ekyle", "password": "password123", "port":9000}
def login(username, password=None):
print(kwargs.get("port"))
Without `mo-kwargs`, passing the `creds` dictionary directly to `login()` would raise a key error
>>> login(**creds)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: login() got an unexpected keyword argument 'port'
The traditional solution is to pass the parameters explicitly:
login(username=creds.username, password=creds.password)
but that can get get tedious when done often, or the parameter list get long. `mo-kwargs` allows you to pass the whole dictionary to the `kwargs` parameter; only the parameters used by the method are used:
@override
def login(username, password=None):
pass
login(kwargs=creds)
# SAME AS
login(username=creds.username, password=creds.password)
## Package all parameters
Your method can accept `kwargs` as a parameter. If it does, ensure it defaults to `None` so that it's not required.
@override
def login(username, password=None, kwargs=None):
print(kwargs.get("username"))
print(kwargs.get("port"))
`kwargs` will always be a dict, possibly empty, with the full set of parameters. This is different from using `**kwargs` which contains only the remainder of the keyword parameters.
>>> creds = {"username": "ekyle", "password": "password123", "port":9000}
>>> login(**creds)
ekyle
9000
Raw data
{
"_id": null,
"home_page": "https://github.com/klahnakoski/mo-kwargs",
"name": "mo-kwargs",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": null,
"author": "Kyle Lahnakoski",
"author_email": "kyle@lahnakoski.com",
"download_url": "https://files.pythonhosted.org/packages/6a/a8/08cc81b4478df401eae2d1340fc217f883f913d06718c31d69b3fcbfdf2e/mo_kwargs-7.671.25036.tar.gz",
"platform": null,
"description": "\r\n# More KWARGS!\r\n\r\nObject destructuring of function parameters for Python!\r\n\r\n[](https://pypi.org/project/mo-kwargs/)\r\n [](https://github.com/klahnakoski/mo-kwargs/actions/workflows/build.yml)\r\n [](https://coveralls.io/github/klahnakoski/mo-kwargs?branch=dev)\r\n[](https://pepy.tech/project/mo-kwargs)\r\n\r\n\r\n## Motivation\r\n\r\nJavascript has [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring), and it can be used for function parameters. This has a couple of benefts over Python's keyword arguments:\r\n\r\n* Extra caller parameters are ignored (eg `f({a, b, c})`)\r\n* Duplicate parameters are handled elegantly (eg `f({a, a})`) \r\n\r\nThe `mo-kwargs` library provides this functionality with the `@override` decorator, with additional benefits:\r\n \r\n * required parameters throw an error if missing, just like regular Python\r\n * all parameters, even ones not in the argument list, are passed in the optional `kwargs` parameter \r\n \r\nThe `@override` decorator adds a `kwargs` argument which can be passed a dict of call parameters; but unlike `**kwargs`, it will not raise duplicate key exceptions.\r\n\r\n## Provide default values\r\n\r\nWe decorate the `login()` function with `@override`. `username` is a required parameter, and `password` will default to `None`. \r\n\r\n @override\r\n def login(username, password=None):\r\n pass\r\n\r\nDefine some `dicts` for use with our `kwargs` parameter:\r\n\r\n creds = {\"userame\": \"ekyle\", \"password\": \"password123\"}\r\n alt_creds = {\"username\": \"klahnakoski\"}\r\n\r\n\r\nThe simplest case is when we use `kwargs` with no overrides\r\n\r\n login(kwargs=creds)\r\n # SAME AS\r\n login(**creds)\r\n # SAME AS\r\n login(username=\"ekyle\", password=\"password123\")\r\n\r\nYou may override any property in `kwargs`: In this case it is `password`\r\n\r\n login(password=\"123\", kwargs=creds)\r\n # SAME AS\r\n login(username=\"ekyle\", password=\"123\")\r\n\r\nThere is no problem with overriding everything in `kwargs`:\r\n\r\n login(username=\"klahnakoski\", password=\"asd213\", kwargs=creds)\r\n # SAME AS\r\n login(username=\"klahnakoski\", password=\"asd213\")\r\n\r\nYou may continue to use `**kwargs`; which provides a way to overlay one parameter template (`creds`) with another (`alt_creds`)\r\n\r\n login(kwargs=creds, **alt_creds)\r\n # SAME AS\r\n login(username=\"klahnakoski\", password=\"password123\")\r\n\r\n## Handle too many parameters\r\n\r\nSometimes your method parameters come from a configuration file, or some other outside source which is outside your control. There may be more parameters than your method is willing to accept. \r\n\r\n creds = {\"username\": \"ekyle\", \"password\": \"password123\", \"port\":9000}\r\n def login(username, password=None):\r\n print(kwargs.get(\"port\"))\r\n\r\nWithout `mo-kwargs`, passing the `creds` dictionary directly to `login()` would raise a key error\r\n\r\n >>> login(**creds)\r\n Traceback (most recent call last):\r\n File \"<stdin>\", line 1, in <module>\r\n TypeError: login() got an unexpected keyword argument 'port'\r\n \r\nThe traditional solution is to pass the parameters explicitly:\r\n\r\n login(username=creds.username, password=creds.password)\r\n\r\nbut that can get get tedious when done often, or the parameter list get long. `mo-kwargs` allows you to pass the whole dictionary to the `kwargs` parameter; only the parameters used by the method are used:\r\n\r\n @override\r\n def login(username, password=None):\r\n pass\r\n \r\n login(kwargs=creds)\r\n # SAME AS\r\n login(username=creds.username, password=creds.password)\r\n\r\n## Package all parameters\r\n\r\nYour method can accept `kwargs` as a parameter. If it does, ensure it defaults to `None` so that it's not required.\r\n\r\n @override\r\n def login(username, password=None, kwargs=None):\r\n print(kwargs.get(\"username\"))\r\n print(kwargs.get(\"port\"))\r\n\r\n`kwargs` will always be a dict, possibly empty, with the full set of parameters. This is different from using `**kwargs` which contains only the remainder of the keyword parameters.\r\n\r\n >>> creds = {\"username\": \"ekyle\", \"password\": \"password123\", \"port\":9000}\r\n >>> login(**creds)\r\n ekyle\r\n 9000\r\n",
"bugtrack_url": null,
"license": "MPL 2.0",
"summary": "Object destructuring of function parameters for Python!",
"version": "7.671.25036",
"project_urls": {
"Homepage": "https://github.com/klahnakoski/mo-kwargs"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "58c8aa9a377e1fbc6314a31b413ead88cb68fa6f2ba7c2690f174e2a4ea8c821",
"md5": "d6091172da3f1128bd2006e8e49533f2",
"sha256": "9e0a48441c63f254cab9ba0b3625f5decadf5557e7cac1bbc6bdebb37bc039e2"
},
"downloads": -1,
"filename": "mo_kwargs-7.671.25036-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d6091172da3f1128bd2006e8e49533f2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 10865,
"upload_time": "2025-02-05T01:28:37",
"upload_time_iso_8601": "2025-02-05T01:28:37.731878Z",
"url": "https://files.pythonhosted.org/packages/58/c8/aa9a377e1fbc6314a31b413ead88cb68fa6f2ba7c2690f174e2a4ea8c821/mo_kwargs-7.671.25036-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6aa808cc81b4478df401eae2d1340fc217f883f913d06718c31d69b3fcbfdf2e",
"md5": "e24d799fe4a90ec9cca0d2eba0d653d5",
"sha256": "d34d245fe4af38fd9820c9658dbd8f7668a651b7eca21da4c2c34105e1291c59"
},
"downloads": -1,
"filename": "mo_kwargs-7.671.25036.tar.gz",
"has_sig": false,
"md5_digest": "e24d799fe4a90ec9cca0d2eba0d653d5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 11188,
"upload_time": "2025-02-05T01:28:39",
"upload_time_iso_8601": "2025-02-05T01:28:39.469858Z",
"url": "https://files.pythonhosted.org/packages/6a/a8/08cc81b4478df401eae2d1340fc217f883f913d06718c31d69b3fcbfdf2e/mo_kwargs-7.671.25036.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-05 01:28:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "klahnakoski",
"github_project": "mo-kwargs",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "mo-kwargs"
}