{"id":21147729,"url":"https://github.com/epicstuff/python-epicstuff","last_synced_at":"2026-05-19T18:31:47.381Z","repository":{"id":220205093,"uuid":"751018079","full_name":"EpicStuff/python-EpicStuff","owner":"EpicStuff","description":"A few somewhat useful (Epic) python objects/functions (Stuff)","archived":false,"fork":false,"pushed_at":"2024-09-05T17:24:23.000Z","size":55,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T04:17:35.463Z","etag":null,"topics":["helper","pypi","python","python-library","python3"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/epicstuff/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EpicStuff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-31T19:16:59.000Z","updated_at":"2024-09-05T17:24:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"d3a991a7-be91-4fde-b521-554e1809cdf1","html_url":"https://github.com/EpicStuff/python-EpicStuff","commit_stats":null,"previous_names":["epicstuff/epicstuff"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EpicStuff%2Fpython-EpicStuff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EpicStuff%2Fpython-EpicStuff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EpicStuff%2Fpython-EpicStuff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EpicStuff%2Fpython-EpicStuff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EpicStuff","download_url":"https://codeload.github.com/EpicStuff/python-EpicStuff/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243589344,"owners_count":20315471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["helper","pypi","python","python-library","python3"],"created_at":"2024-11-20T09:18:11.698Z","updated_at":"2026-05-19T18:31:47.373Z","avatar_url":"https://github.com/EpicStuff.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EpicStuff\r\n\r\nA few somewhat useful (Epic) python objects/functions (Stuff).\r\n\r\n## Installation\r\n\r\n```bash\r\npip install epicstuff\r\n```\r\n\r\n## Dict\r\n\r\nLets you access a dictionary's keys as attributes\r\n\r\n### JDict version\r\n\r\nPoints to a target instead of converting it into a (new) `Dict` object. Useful for when your \"target\" is say, a `CommentedMap` and you don't want to loose the comments.\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import Dict\r\n\r\nd = Dict({})\r\n\r\nd.x = 1\r\n```\r\n\r\n### BoxDict version\r\n\r\nSimpler (less features) than [`Box`](https://pypi.org/project/python-box/) but with more features (recursive conversion and creation on access) than [`jdict`](https://pypi.org/project/pyjdict/) (and without some of the \"extra\" stuff)\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import Dict\r\n\r\nd = Dict({\"a\": 1, \"b\": {\"c\": 2, \"d\": 3}}, _convert=None)\r\n\r\nprint(d.b.c)  # 2\r\n```\r\n\r\n## Rich Trace\r\n\r\nEasily install terminal-wide `rich.traceback` and use helpers to ensure pretty tracebacks with async functions.\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import run_install_trace\r\n```\r\n\r\n- or:\r\n\r\n```python\r\nfrom epicstuff import rich_trace\r\n\r\n@rich_trace\r\nasync def some_func():\r\n\traise Exception\r\nsome_func()\r\n```\r\n\r\n- or:\r\n\r\n```python\r\n@rich_trace(_return=0)\r\nasync def some_func():\r\n\traise Exception\r\nsome_func()\r\n```\r\n\r\n- or:\r\n\r\n```python\r\nwith rich_trace():\r\n\traise Exception\r\n```\r\n\r\n## Bar\r\n\r\nMakes using nested progress bars from rich.progress easier\r\n\r\n- Example:\r\n\r\nbasically lets you replace\r\n\r\n```python\r\nfrom rich.progress import Progress\r\n\r\nwith Progress() as progress:\r\n\ttask = progress.add_task(\"task\", total=100)\r\n\tfor i in range(100):\r\n\t\tsub_task = progress.add_task(\"subtask\", total=100)\r\n\t\tfor j in range(100):\r\n\t\t\ttime.sleep(0.01)  # some task\r\n\r\n\t\t\tprogress.update(sub_task, advance=1)\r\n\r\n\t\tprogress.remove_task(sub_task)\r\n\t\tprogress.update(task, advance=1)\r\n\r\n```\r\n\r\nwith\r\n\r\n```python\r\nfrom epicstuff import Bar\r\n\r\nwith Bar() as bar:\r\n\tfor i in bar(range(100)):\r\n\t\tfor j in bar(range(100), transient=True):\r\n\t\t\ttime.sleep(0.01)  # some task\r\n```\r\n\r\nwith minor extra features (fancier default bar)\r\n\r\n\r\n## Timer\r\n\r\na simple timer to time execution of code a code segment\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import timer\r\n\r\nwith timer():\r\n\tpass  # some code\r\n\r\n# outputs: Time elapsed: 0.0 seconds\r\n# message can be changed by passing a string with {} to timer\r\n```\r\n\r\n## s\r\n\r\nAn autoformatting string. Removes extra indent and leading/trailing newlines. (Not quite done yet.)\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import s\r\n\r\nstring = s('''\r\n\tline 1\r\n\t\tline 2\r\n\t\t\tline 3\r\n''') + 'line 4'\r\n\r\nprint(s)\r\n# line 1\r\n# \tline 2\r\n# \t\tline 3\r\n# line 4\r\n```\r\n\r\n## Permissify\r\n\r\nmake function ignore extra arguments instead of raising an error.\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import perm\r\n\r\ndef tmp(a, b=2): ...\r\n\r\nperm(tmp)(1, 2, b=3, c=5)  # this will run without raising TypeError\r\n```\r\n\r\n## fix_import\r\n\r\nLets you do relative imports and absolute imports from parent folder without having to run the file as a module.\r\n\r\n- Example:\r\n\r\n```python\r\nfrom epicstuff import run_fix_import\r\n```\r\n\r\n- or\r\n\r\n```python\r\nfrom epicstuff import fix_import\r\nfix_import('src')\r\n# or\r\nfix_import('..')\r\n\r\nfrom src.stuff import *\r\n# or\r\nfrom ..stuff import *\r\n```\r\n\r\n\r\n## Stuff\r\n\r\nextra functions:\r\n\r\n- `open`: overwrites `open` with `Path.open` and `encoding='utf8'`\r\n\t- `with open('file') as f: ...`\r\n- `wrap`: just a renamed `functools.partial`\r\n- `rmap`: `map` but recursive for lists and dicts\r\n\t- takes `list` or `dict` and 2 functions, will apply function 1 to all keys and function 2 to all values\r\n- `Tee`: Text stream that writes to multiple underlying streams. (Example: redirect stdout to terminal and a file)\r\n- `Pointer`: an object you can kinda use like a pointer. (Example `number = Pointer(5), number._t = 6`)\r\n\r\n## TODO:\r\n\r\n- [ ] when doing bar in bar with the second bar being transient, make so that the dots continue from where the previous bar left off\r\n- [ ] implement auto transient for bar in bar\r\n- [ ] add and implement simple=False for .Bar.track()\r\n- [ ] look into using `wrapt.ObjectProxy`\r\n\r\n## Stuff:\r\n\r\n- Note to self:\r\n\t- \"self install\" using `pip install -U -e .`\r\n\t- upload by running `python -m build` then `twine upload --skip-existing dist/*`\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepicstuff%2Fpython-epicstuff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fepicstuff%2Fpython-epicstuff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepicstuff%2Fpython-epicstuff/lists"}