https://github.com/egpbos/kwandl
Keyword arguments handled
https://github.com/egpbos/kwandl
Last synced: 25 days ago
JSON representation
Keyword arguments handled
- Host: GitHub
- URL: https://github.com/egpbos/kwandl
- Owner: egpbos
- License: apache-2.0
- Created: 2022-02-19T15:16:02.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-08-10T14:12:01.000Z (almost 3 years ago)
- Last Synced: 2025-04-25T00:46:47.690Z (about 1 month ago)
- Language: Python
- Size: 104 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Contributing: docs/CONTRIBUTING.md
- License: LICENSE
- Code of conduct: docs/CODE_OF_CONDUCT.md
- Citation: CITATION.cff
Awesome Lists containing this project
README
[](https://fair-software.eu)
[](https://github.com/egpbos/kwandl/actions/workflows/build.yml)
[](https://pypi.python.org/project/kwandl/)
[](https://doi.org/10.5281/zenodo.6371612)# `kwandl`: Keyword arguments handled
## InstallationInstall `kwandl` using `pip`:
```console
python3 -m pip install kwandl
```To install the most recent development version directly from the GitHub repository run:
```console
python3 -m pip install git+https://github.com/egpbos/kwandl.git
```## Usage
`kwandl` is essentially a box of magic tricks to make working with `kwargs` smoother.
### Forward passing only relevant `kwargs`
Say you have a function `top` which takes `**kwargs` and passes them on to `ding` and `boop`:
```python
def top(**kwargs):
ding(**kwargs)
boop(**kwargs)
```
Only problem is: `ding` and `boop` have different sets of keyword arguments:
```python
def ding(dingo=1, dinga=2):
...def boop(boopie=3, boonk=4):
...
```
This means `top(dingo="blurg", boonk=None)` will fail with a `TypeError`, because `boonk` will be passed to `ding` and `dingo` will be passed to `boop`, both of which are invalid.`kwandl` solves this for you with one simple decorator:
```python
@kwandl.forward
def top(**kwargs):
ding(**kwargs)
boop(**kwargs)
```
This _Just Works™_.It does so by modifying the abstract syntax tree (AST) of the function calls with `kwargs` as argument so that `kwargs` is effectively replaced by `kwandl.get_kwargs_applicable_to_function(ding, kwargs)` (or `boop` instead of `ding` depending on the calling function).
An alternative way to use this `kwandl` functionality then is to use `get_kwargs_applicable_to_function` directly:```python
def top(**kwargs):
ding(**kwandl.get_kwargs_applicable_to_function(ding, kwargs))
boop(**kwandl.get_kwargs_applicable_to_function(boop, kwargs))
```Note, however, that `@kwandl.forward` does a bit more: it also checks whether kwargs contains keyword arguments that are a match to neither `ding` nor `boop` and raises a `TypeError` if so.
A complete alternative notation for `@kwandl.forward` would then be:```python
def top(**kwargs):
ding_kwargs = kwandl.get_kwargs_applicable_to_function(ding, kwargs)
boop_kwargs = kwandl.get_kwargs_applicable_to_function(boop, kwargs)unexpected_keywords = set(kwargs) - set(ding_kwargs) - set(boop_kwargs)
if unexpected_keywords:
raise TypeError(f"top() got an unexpected keyword argument '{unexpected_keywords.pop()}'")ding(**ding_kwargs)
boop(**boop_kwargs)
```
The motivation behind this package should now become clearer: the amount of boilerplate necessary to solve what in my mind should not be such a huge problem is ... well, huge.## Documentation
[](https://kwandl.readthedocs.io/en/latest/?badge=latest)For more details, see the [full documentation on Readthedocs](https://kwandl.readthedocs.io/en/latest#Contents).
## ContributingIf you want to contribute to the development of `kwandl`,
have a look at the [contribution guidelines](https://kwandl.readthedocs.io/en/latest/CONTRIBUTING.html).## Credits
This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [NLeSC/python-template](https://github.com/NLeSC/python-template).