# Hacky config parser - parses ConfigParser-compatible files / sys.argv and changes the defaults of functions
### pip install hackycfgparser
#### Tested against Windows 10 / Python 3.10 / Anaconda
The goal of this project is to create a decorator function that can modify the default arguments of a given function using values passed through both ConfigParser-compatible files and command line arguments. To achieve this, we first check if the input function is callable or None. Then, we retrieve the global dictionary of the calling frame and define a decorator function.
The decorator function works by modifying the default arguments of the input function based on the values passed through the command line arguments. To do this, we first retrieve the variable names and annotations of the input function and create a dictionary of all the annotations. We then iterate through the default arguments of the input function and attempt to convert them to the appropriate data type based on the annotations. If the conversion fails, we try all possible data types until a successful conversion is made.
Finally, the modified default arguments are set, and the input function is called with the modified arguments. This allows for greater flexibility and customization when working with functions, making it easier to pass in arguments from different sources without needing to modify the function nor the function calls themselves.
There is also a standalone version of the sys.argv parser:
https://github.com/hansalemaos/hackyargparser
### How to use it
```python
from hackycfgparser import load_config_file_vars, add_config, config
load_config_file_vars(cfgfile=r"C:\testcfg.ini", onezeroasboolean=False)
config.helptext = (
"Error! --f2_a, --f2_b, --f1_a are mandatory!" # The help text to be printed
)
config.kill_when_not_there(
("--f2_a", "--f2_b", "--f1_a")
) # If those arguments are not passed, config.helptext will be printed, and sys.exit will be called
config.stop_after_kill = True # Stop after printing config.helptext -> input()
# example of a config file (put Iterables in double quotes"")
'''[book]
title: The Python Standard Library
author: Fredrik Lundh
email: fredrik@pythonware.com
version: 2.0-001115
pages: 250
f1_a: 14.5
f1_b: 22
f2_a: 1444.5
f2_b: 2244
f3_a: "(14446.5,20,33)"
f3_b: 2266
mvar:1099324
didi:"{2:3,5:6}"
dudu:"{2,3,5,6}"'''
@add_config
def function10(
didi: dict | None = None,
dudu: set | None = None,
mvar: int = 10,
):
print(didi, dudu)
return didi, dudu, mvar
@add_config
def function1(
f1_a: int | float | None = None,
f1_b: int | float = 1,
mvar: int = 10,
):
print(f1_b * f1_a * mvar)
return f1_a, f1_b, mvar
@add_config
def function2(
f2_a: int | float | None = None,
f2_b: int | float | None = None,
mvar: int = 10,
):
print(f2_a * f2_b * mvar)
return f2_a, f2_b, mvar
@add_config
def function3(
f3_a: list | tuple = (),
f3_b: int | float = 1,
):
for l in f3_a:
print(l + f3_b)
return set(f3_a)
def function4(
f3_a: list | tuple = (),
f3_b: int | float = 1,
):
print("i am not decorated")
print(f"{f3_a=}, {f3_b=}")
return set(f3_a)
@add_config
def baba(title: str = "", email: str = "", pages: int = 0):
print(title, email, pages)
@add_config
def baba2(title2: str = "", email2: str = "", pages2: int = 0):
print(title2, email2, pages2)
return title2 + email2
print(f"\n=========\n{function2()=}")
print(f"\n=========\n{function1()=}")
print(f"\n=========\n{function3()=}")
print(f"\n=========\n{function4()=}")
print(f"\n=========\n{baba()=}")
print(f"\n=========\n{function10()=}")
print(f"\n=========\n{baba2()=}")
# (dfdir) PS C:\ProgramData\anaconda3\envs\dfdir> .\python.exe .\hackycfg.py --title2 bababadxd --email2 ooooooo pages2 555
# 3563412574392.0
#
# =========
# function2()=(1444.5, 2244, 1099324)
# 350684356.0
#
# =========
# function1()=(14.5, 22, 1099324)
# 16712.5
# 2286
# 2299
#
# =========
# function3()={33, 20, 14446.5}
# i am not decorated
# f3_a=(), f3_b=1
#
# =========
# function4()=set()
# 'The Python Standard Library' 'fredrik@pythonware.com' 250
#
# =========
# baba()=None
# {2: 3, 5: 6} {2, 3, 5, 6}
#
# =========
# function10()=({2: 3, 5: 6}, {2, 3, 5, 6}, 1099324)
# bababadxd ooooooo 0
#
# =========
# baba2()='bababadxdooooooo'
```
Raw data
{
"_id": null,
"home_page": "https://github.com/hansalemaos/hackycfgparser",
"name": "hackycfgparser",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "hacky,config,parser,decorator",
"author": "Johannes Fischer",
"author_email": "aulasparticularesdealemaosp@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/b9/26/1c1f9cbe919bb9c8a4f49dcdb4afc03184f0e3a2db9e6971a08ab8509761/hackycfgparser-0.12.tar.gz",
"platform": null,
"description": "# Hacky config parser - parses ConfigParser-compatible files / sys.argv and changes the defaults of functions\r\n\r\n### pip install hackycfgparser\r\n\r\n#### Tested against Windows 10 / Python 3.10 / Anaconda\r\n\r\n\r\nThe goal of this project is to create a decorator function that can modify the default arguments of a given function using values passed through both ConfigParser-compatible files and command line arguments. To achieve this, we first check if the input function is callable or None. Then, we retrieve the global dictionary of the calling frame and define a decorator function.\r\n\r\nThe decorator function works by modifying the default arguments of the input function based on the values passed through the command line arguments. To do this, we first retrieve the variable names and annotations of the input function and create a dictionary of all the annotations. We then iterate through the default arguments of the input function and attempt to convert them to the appropriate data type based on the annotations. If the conversion fails, we try all possible data types until a successful conversion is made.\r\n\r\nFinally, the modified default arguments are set, and the input function is called with the modified arguments. This allows for greater flexibility and customization when working with functions, making it easier to pass in arguments from different sources without needing to modify the function nor the function calls themselves.\r\n\r\nThere is also a standalone version of the sys.argv parser: \r\nhttps://github.com/hansalemaos/hackyargparser\r\n\r\n### How to use it\r\n\r\n```python\r\n\r\n\r\nfrom hackycfgparser import load_config_file_vars, add_config, config\r\n\r\nload_config_file_vars(cfgfile=r\"C:\\testcfg.ini\", onezeroasboolean=False)\r\nconfig.helptext = (\r\n \"Error! --f2_a, --f2_b, --f1_a are mandatory!\" # The help text to be printed\r\n)\r\nconfig.kill_when_not_there(\r\n (\"--f2_a\", \"--f2_b\", \"--f1_a\")\r\n) # If those arguments are not passed, config.helptext will be printed, and sys.exit will be called\r\nconfig.stop_after_kill = True # Stop after printing config.helptext -> input()\r\n\r\n\r\n# example of a config file (put Iterables in double quotes\"\")\r\n'''[book]\r\ntitle: The Python Standard Library\r\nauthor: Fredrik Lundh\r\nemail: fredrik@pythonware.com\r\nversion: 2.0-001115\r\npages: 250\r\nf1_a: 14.5\r\nf1_b: 22\r\nf2_a: 1444.5\r\nf2_b: 2244\r\nf3_a: \"(14446.5,20,33)\"\r\nf3_b: 2266\r\nmvar:1099324\r\ndidi:\"{2:3,5:6}\"\r\ndudu:\"{2,3,5,6}\"'''\r\n\r\n\r\n@add_config\r\ndef function10(\r\n didi: dict | None = None,\r\n dudu: set | None = None,\r\n mvar: int = 10,\r\n):\r\n print(didi, dudu)\r\n return didi, dudu, mvar\r\n\r\n\r\n@add_config\r\ndef function1(\r\n f1_a: int | float | None = None,\r\n f1_b: int | float = 1,\r\n mvar: int = 10,\r\n):\r\n print(f1_b * f1_a * mvar)\r\n return f1_a, f1_b, mvar\r\n\r\n\r\n@add_config\r\ndef function2(\r\n f2_a: int | float | None = None,\r\n f2_b: int | float | None = None,\r\n mvar: int = 10,\r\n):\r\n print(f2_a * f2_b * mvar)\r\n\r\n return f2_a, f2_b, mvar\r\n\r\n\r\n@add_config\r\ndef function3(\r\n f3_a: list | tuple = (),\r\n f3_b: int | float = 1,\r\n):\r\n for l in f3_a:\r\n print(l + f3_b)\r\n\r\n return set(f3_a)\r\n\r\n\r\ndef function4(\r\n f3_a: list | tuple = (),\r\n f3_b: int | float = 1,\r\n):\r\n print(\"i am not decorated\")\r\n print(f\"{f3_a=}, {f3_b=}\")\r\n\r\n return set(f3_a)\r\n\r\n\r\n@add_config\r\ndef baba(title: str = \"\", email: str = \"\", pages: int = 0):\r\n print(title, email, pages)\r\n\r\n\r\n@add_config\r\ndef baba2(title2: str = \"\", email2: str = \"\", pages2: int = 0):\r\n print(title2, email2, pages2)\r\n return title2 + email2\r\n\r\n\r\nprint(f\"\\n=========\\n{function2()=}\")\r\nprint(f\"\\n=========\\n{function1()=}\")\r\nprint(f\"\\n=========\\n{function3()=}\")\r\nprint(f\"\\n=========\\n{function4()=}\")\r\nprint(f\"\\n=========\\n{baba()=}\")\r\nprint(f\"\\n=========\\n{function10()=}\")\r\nprint(f\"\\n=========\\n{baba2()=}\")\r\n\r\n# (dfdir) PS C:\\ProgramData\\anaconda3\\envs\\dfdir> .\\python.exe .\\hackycfg.py --title2 bababadxd --email2 ooooooo pages2 555\r\n# 3563412574392.0\r\n#\r\n# =========\r\n# function2()=(1444.5, 2244, 1099324)\r\n# 350684356.0\r\n#\r\n# =========\r\n# function1()=(14.5, 22, 1099324)\r\n# 16712.5\r\n# 2286\r\n# 2299\r\n#\r\n# =========\r\n# function3()={33, 20, 14446.5}\r\n# i am not decorated\r\n# f3_a=(), f3_b=1\r\n#\r\n# =========\r\n# function4()=set()\r\n# 'The Python Standard Library' 'fredrik@pythonware.com' 250\r\n#\r\n# =========\r\n# baba()=None\r\n# {2: 3, 5: 6} {2, 3, 5, 6}\r\n#\r\n# =========\r\n# function10()=({2: 3, 5: 6}, {2, 3, 5, 6}, 1099324)\r\n# bababadxd ooooooo 0\r\n#\r\n# =========\r\n# baba2()='bababadxdooooooo'\r\n\r\n\r\n\r\n```\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Hacky config parser - parses ConfigParser-compatible files / sys.argv and changes the defaults of functions",
"version": "0.12",
"project_urls": {
"Homepage": "https://github.com/hansalemaos/hackycfgparser"
},
"split_keywords": [
"hacky",
"config",
"parser",
"decorator"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a89a7633c2795306bb9153ec7c641f6931a14719ee1e4a78ea92e9925754d493",
"md5": "a510805a17a031427e761574271f86dd",
"sha256": "d2105dcf468f78eb754fc416567bde61f041c8f8b6aa5fe1a82301e288833de5"
},
"downloads": -1,
"filename": "hackycfgparser-0.12-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a510805a17a031427e761574271f86dd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 10731,
"upload_time": "2023-05-01T02:47:47",
"upload_time_iso_8601": "2023-05-01T02:47:47.019885Z",
"url": "https://files.pythonhosted.org/packages/a8/9a/7633c2795306bb9153ec7c641f6931a14719ee1e4a78ea92e9925754d493/hackycfgparser-0.12-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b9261c1f9cbe919bb9c8a4f49dcdb4afc03184f0e3a2db9e6971a08ab8509761",
"md5": "e4215a9fad7d40b62dc3351fdff3ede2",
"sha256": "60d787b378507572bcab1505d8f3adfa6743e0983fb22f327f94e86b9a1fb7d3"
},
"downloads": -1,
"filename": "hackycfgparser-0.12.tar.gz",
"has_sig": false,
"md5_digest": "e4215a9fad7d40b62dc3351fdff3ede2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 7566,
"upload_time": "2023-05-01T02:47:49",
"upload_time_iso_8601": "2023-05-01T02:47:49.221505Z",
"url": "https://files.pythonhosted.org/packages/b9/26/1c1f9cbe919bb9c8a4f49dcdb4afc03184f0e3a2db9e6971a08ab8509761/hackycfgparser-0.12.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-01 02:47:49",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hansalemaos",
"github_project": "hackycfgparser",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "deepcopyall",
"specs": []
},
{
"name": "flatten_any_dict_iterable_or_whatsoever",
"specs": []
},
{
"name": "tolerant_isinstance",
"specs": []
}
],
"lcname": "hackycfgparser"
}