# Docstring Expander
This project addresses a common problem with the development of python packages in which there several higher level functions that have are many keyword options that are processed by low level functions. Typically, the higher level functions use `**kwargs` to pass keywords transparently to the lower level functions. This is an excellent use of python's capabilities.
But it creates a problem when used with intellisense in that the keyword options are only exposed at the lower level.
To illustrate, consider the following low level plotting function that is called by two plotting functions.
def lowlevelPlot(data, num_col:int=2, num_row:int=3, bins=100):
"""
General plot function.
Parameters
----------
num_col: Number of columns of plots
num_row: Number of rows of plots
bins: Number of bins
"""
...
def plotHist(data:np.ndarray, num_col:int=2, num_row:int=3, bins=100):
"""
Plot a histogram.
Parameters
----------
num_col: Number of columns of plots
default: 2
num_row: Number of rows of plots
default: 3
bins: Number of bins
default: 100
"""
...
lowlevelPlot(num_col=num_col, num_row=num_row, bins=bins)
def plotTimeseries(data:np.ndarray, num_col:int=2, num_row:int=3):
"""
Plot a histogram.
Parameters
----------
num_col: Number of columns of plots
default: 2
num_row: Number of rows of plots
"""
...
lowlevelPlot(num_col=num_col, num_row=num_row)
`
Since there is an almost unlimited number of options for plotting, we expect that the keyword options for ``genPlot`` will grow over time. For example, we may want to add options for a title, the position of the title, and its font. These should be transparently available to `hist` and `timeseries`, without changing their signatures or docstrings. So, a more maintainable version of these functions is:
def plotHist(data, **kwargs):
"""
Plot a histogram.
Parameters
----------
See lowlevelPlot.
"""
...
lowlevelPlot(**kwargs)
def plotTimeseries(data:np.ndarray, **kwargs):
"""
Plot a histogram.
Parameters
----------
See lowlevelPlot.
"""
...
lowlevelPlot(**kwargs)
But now intellisense doesn't work since the options exposed for a function by intellisese are what's in the docstring of function.
`docstring_expander` provides another solution. Suppose we have the following dictionary that describes all keyword arguments for `genPlot`:
import docstring_expander as de
kwargs = [
de.Kwarg('num_col', dtype=int, default=2, doc='Number of columns of plots'),
de.Kwarg('num_row', dtype=int, default=3, doc='Number of rows of plots'),
de.Kwarg(name='bins' default=100, doc='Number of bins'),
]
We define a few keyword arguments as common to most plotting functions.
base = ['num_col', 'num_row']
Then we can write:
@de.Expander(kwargs, base, includes=['bins'])
def plotHist(data:np.ndarray, **kwargs):
"""
Plot a histogram.
Parameters
----------
#@expand
"""
...
lowlevelPlot(**kwargs)
@de.Expander(kwargs, base)
def plotTimeseries(data:np.ndarray, **kwargs):
"""
Plot a histogram.
Parameters
----------
#@exapnd
"""
...
lowlevelPlot(**kwargs)
For `plotHist`, the decorator replaces `#@expand` with:
num_col: int
Number of columns of plots
default: 2
num_row: int
Number of rows of plots
default: 3
bins:
Number of bins
default: 100
The keyword arguments in the expansion are those in `base` plus those in `includes` minus those in `excludes`.
Raw data
{
"_id": null,
"home_page": "https://github.com/joseph-hellerstein/docstring_expander.git",
"name": "docstring-expander",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Joseph L. Hellerstein",
"author_email": "jlheller@uw.edu",
"download_url": "https://files.pythonhosted.org/packages/a4/0e/18b0b2947c017704cbff62ff7ef24118a6ecfc7913fc194186a72aedff1a/docstring_expander-0.23.tar.gz",
"platform": "",
"description": "# Docstring Expander\n\nThis project addresses a common problem with the development of python packages in which there several higher level functions that have are many keyword options that are processed by low level functions. Typically, the higher level functions use `**kwargs` to pass keywords transparently to the lower level functions. This is an excellent use of python's capabilities.\nBut it creates a problem when used with intellisense in that the keyword options are only exposed at the lower level.\n\nTo illustrate, consider the following low level plotting function that is called by two plotting functions.\n\n \n def lowlevelPlot(data, num_col:int=2, num_row:int=3, bins=100):\n \"\"\"\n General plot function.\n \n Parameters\n ----------\n num_col: Number of columns of plots\n num_row: Number of rows of plots\n bins: Number of bins\n \"\"\"\n ...\n \n def plotHist(data:np.ndarray, num_col:int=2, num_row:int=3, bins=100): \n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n num_col: Number of columns of plots\n default: 2\n num_row: Number of rows of plots\n default: 3\n bins: Number of bins\n default: 100\n \"\"\"\n ...\n lowlevelPlot(num_col=num_col, num_row=num_row, bins=bins)\n \n def plotTimeseries(data:np.ndarray, num_col:int=2, num_row:int=3):\n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n num_col: Number of columns of plots\n default: 2\n num_row: Number of rows of plots\n \"\"\"\n ...\n lowlevelPlot(num_col=num_col, num_row=num_row)\n`\n\nSince there is an almost unlimited number of options for plotting, we expect that the keyword options for ``genPlot`` will grow over time. For example, we may want to add options for a title, the position of the title, and its font. These should be transparently available to `hist` and `timeseries`, without changing their signatures or docstrings. So, a more maintainable version of these functions is:\n\n def plotHist(data, **kwargs):\n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n See lowlevelPlot.\n \"\"\"\n ...\n lowlevelPlot(**kwargs)\n \n def plotTimeseries(data:np.ndarray, **kwargs):\n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n See lowlevelPlot.\n \"\"\"\n ...\n lowlevelPlot(**kwargs)\n \nBut now intellisense doesn't work since the options exposed for a function by intellisese are what's in the docstring of function.\n\n`docstring_expander` provides another solution. Suppose we have the following dictionary that describes all keyword arguments for `genPlot`:\n\n import docstring_expander as de\n \n kwargs = [\n de.Kwarg('num_col', dtype=int, default=2, doc='Number of columns of plots'),\n de.Kwarg('num_row', dtype=int, default=3, doc='Number of rows of plots'),\n de.Kwarg(name='bins' default=100, doc='Number of bins'),\n ]\n We define a few keyword arguments as common to most plotting functions.\n \n base = ['num_col', 'num_row']\n \nThen we can write:\n \n @de.Expander(kwargs, base, includes=['bins'])\n def plotHist(data:np.ndarray, **kwargs):\n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n #@expand\n \"\"\"\n ...\n lowlevelPlot(**kwargs)\n \n @de.Expander(kwargs, base)\n def plotTimeseries(data:np.ndarray, **kwargs):\n \"\"\"\n Plot a histogram.\n \n Parameters\n ----------\n #@exapnd\n \"\"\"\n ...\n lowlevelPlot(**kwargs)\n \n\nFor `plotHist`, the decorator replaces `#@expand` with:\n\n num_col: int\n Number of columns of plots\n default: 2\n num_row: int\n Number of rows of plots\n default: 3\n bins: \n Number of bins\n default: 100\n\n\nThe keyword arguments in the expansion are those in `base` plus those in `includes` minus those in `excludes`.",
"bugtrack_url": null,
"license": "",
"summary": "Enables intellisense for **kwargs",
"version": "0.23",
"project_urls": {
"Homepage": "https://github.com/joseph-hellerstein/docstring_expander.git"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a40e18b0b2947c017704cbff62ff7ef24118a6ecfc7913fc194186a72aedff1a",
"md5": "777072b9f3cbc459d5a0ae9bcf3b1141",
"sha256": "01d881bd22c8f4ebbf62db846e3c0a80b9dc9888907fdce9a82c52a6495014ef"
},
"downloads": -1,
"filename": "docstring_expander-0.23.tar.gz",
"has_sig": false,
"md5_digest": "777072b9f3cbc459d5a0ae9bcf3b1141",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 4038,
"upload_time": "2020-08-29T00:39:36",
"upload_time_iso_8601": "2020-08-29T00:39:36.015797Z",
"url": "https://files.pythonhosted.org/packages/a4/0e/18b0b2947c017704cbff62ff7ef24118a6ecfc7913fc194186a72aedff1a/docstring_expander-0.23.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2020-08-29 00:39:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "joseph-hellerstein",
"github_project": "docstring_expander",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "nose",
"specs": []
},
{
"name": "twine",
"specs": []
}
],
"lcname": "docstring-expander"
}