{"id":20466059,"url":"https://github.com/withprecedent/naru","last_synced_at":"2025-03-05T12:29:28.524Z","repository":{"id":197279731,"uuid":"698348905","full_name":"WithPrecedent/naru","owner":"WithPrecedent","description":"Python tools for transforming and modifying objects","archived":false,"fork":false,"pushed_at":"2024-04-05T22:14:19.000Z","size":720,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-16T01:16:57.356Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/WithPrecedent.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-09-29T17:59:05.000Z","updated_at":"2023-09-29T18:00:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"9123bfca-20cc-4a15-96ac-cb0494ad49fe","html_url":"https://github.com/WithPrecedent/naru","commit_stats":null,"previous_names":["withprecedent/naru"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fnaru","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fnaru/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fnaru/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithPrecedent%2Fnaru/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WithPrecedent","download_url":"https://codeload.github.com/WithPrecedent/naru/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242027494,"owners_count":20060108,"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":[],"created_at":"2024-11-15T13:21:21.255Z","updated_at":"2025-03-05T12:29:28.480Z","avatar_url":"https://github.com/WithPrecedent.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# modify\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/WithPrecedent/modify/blob/main/docs/images/logo.png\" alt=\"logo\" style=\"width:200px;\"/\u003e\n\u003c/p\u003e\n\n| | |\n| --- | --- |\n| Version | [![PyPI Latest Release](https://img.shields.io/pypi/v/modify.svg?style=for-the-badge\u0026color=steelblue\u0026label=PyPI\u0026logo=PyPI\u0026logoColor=yellow)](https://pypi.org/project/modify/) [![GitHub Latest Release](https://img.shields.io/github/v/tag/WithPrecedent/modify?style=for-the-badge\u0026color=navy\u0026label=GitHub\u0026logo=github)](https://github.com/WithPrecedent/modify/releases)\n| Status | [![Build Status](https://img.shields.io/github/actions/workflow/status/WithPrecedent/modify/ci.yml?branch=main\u0026style=for-the-badge\u0026color=cadetblue\u0026label=Tests\u0026logo=pytest)](https://github.com/WithPrecedent/modify/actions/workflows/ci.yml?query=branch%3Amain) [![Development Status](https://img.shields.io/badge/Development-Active-seagreen?style=for-the-badge\u0026logo=git)](https://www.repostatus.org/#active) [![Project Stability](https://img.shields.io/pypi/status/modify?style=for-the-badge\u0026logo=pypi\u0026label=Stability\u0026logoColor=yellow)](https://pypi.org/project/modify/)\n| Documentation | [![Hosted By](https://img.shields.io/badge/Hosted_by-Github_Pages-blue?style=for-the-badge\u0026color=navy\u0026logo=github)](https://WithPrecedent.github.io/modify)\n| Tools | [![Documentation](https://img.shields.io/badge/MkDocs-magenta?style=for-the-badge\u0026color=deepskyblue\u0026logo=markdown\u0026labelColor=gray)](https://squidfunk.github.io/mkdocs-material/) [![Linter](https://img.shields.io/endpoint?style=for-the-badge\u0026url=https://raw.githubusercontent.com/charliermarsh/Ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/Ruff) [![Dependency Manager](https://img.shields.io/badge/PDM-mediumpurple?style=for-the-badge\u0026logo=affinity\u0026labelColor=gray)](https://PDM.fming.dev) [![Pre-commit](https://img.shields.io/badge/pre--commit-darkolivegreen?style=for-the-badge\u0026logo=pre-commit\u0026logoColor=white\u0026labelColor=gray)](https://github.com/TezRomacH/python-package-template/blob/master/.pre-commit-config.yaml) [![CI](https://img.shields.io/badge/GitHub_Actions-navy?style=for-the-badge\u0026logo=githubactions\u0026labelColor=gray\u0026logoColor=white)](https://github.com/features/actions) [![Editor Settings](https://img.shields.io/badge/Editor_Config-paleturquoise?style=for-the-badge\u0026logo=editorconfig\u0026labelColor=gray)](https://editorconfig.org/) [![Repository Template](https://img.shields.io/badge/snickerdoodle-bisque?style=for-the-badge\u0026logo=cookiecutter\u0026labelColor=gray)](https://www.github.com/WithPrecedent/modify) [![Dependency Maintainer](https://img.shields.io/badge/dependabot-navy?style=for-the-badge\u0026logo=dependabot\u0026logoColor=white\u0026labelColor=gray)](https://github.com/dependabot)\n| Compatibility | [![Compatible Python Versions](https://img.shields.io/pypi/pyversions/modify?style=for-the-badge\u0026color=steelblue\u0026label=Python\u0026logo=python\u0026logoColor=yellow)](https://pypi.python.org/pypi/modify/) [![Linux](https://img.shields.io/badge/Linux-lightseagreen?style=for-the-badge\u0026logo=linux\u0026labelColor=gray\u0026logoColor=white)](https://www.linux.org/) [![MacOS](https://img.shields.io/badge/MacOS-snow?style=for-the-badge\u0026logo=apple\u0026labelColor=gray)](https://www.apple.com/macos/) [![Windows](https://img.shields.io/badge/windows-blue?style=for-the-badge\u0026logo=Windows\u0026labelColor=gray\u0026color=orangered)](https://www.microsoft.com/en-us/windows?r=1)\n| Stats | [![PyPI Download Rate (per month)](https://img.shields.io/pypi/dm/modify?style=for-the-badge\u0026color=steelblue\u0026label=Downloads%20💾\u0026logo=pypi\u0026logoColor=yellow)](https://pypi.org/project/modify) [![GitHub Stars](https://img.shields.io/github/stars/WithPrecedent/modify?style=for-the-badge\u0026color=navy\u0026label=Stars%20⭐\u0026logo=github)](https://github.com/WithPrecedent/modify/stargazers) [![GitHub Contributors](https://img.shields.io/github/contributors/WithPrecedent/modify?style=for-the-badge\u0026color=navy\u0026label=Contributors%20🙋\u0026logo=github)](https://github.com/WithPrecedent/modify/graphs/contributors) [![GitHub Issues](https://img.shields.io/github/issues/WithPrecedent/modify?style=for-the-badge\u0026color=navy\u0026label=Issues%20📘\u0026logo=github)](https://github.com/WithPrecedent/modify/graphs/contributors) [![GitHub Forks](https://img.shields.io/github/forks/WithPrecedent/modify?style=for-the-badge\u0026color=navy\u0026label=Forks%20🍴\u0026logo=github)](https://github.com/WithPrecedent/modify/forks)\n| | |\n\n-----\n\n## What is modify?\n\n`modify` gives you tools to modify and transfrom Python objects using a universal,\nintuitive syntax.\n\n## Why use modify?\n\nRather than remembering every command and its parameters for modifying and\ntransforming Python objects, you can simply import `modify` and use the same\nsyntax and arguments for any supported modification or transforming command.\n`modify` is:\n\n* **Lightweight**: it has no dependencies and a miniscule memory footprint.\n* **Intuitive**: every function name uses obvious, readable terms (e.g.,\n  functions that add something uses the prefix \"add\", functions that remove\n  something use the prefix \"drop\", etc.).\n* **Flexible**: you can either call a general or specific function.\n  For example, as discussed below, to add a prefix to every `str` item in a\n  list-like object, you can call `add_prefix_to_list` or `add_prefix`. In the\n  latter case, if the function detects the passed item is a `MutableSequence`,\n  calls `add_prefix_to_list` automatically.\n\n## Getting started\n\n### Installation\n\nTo install `modify`, use `pip`:\n\n```sh\npip install modify\n```\n\n### Usage\n\nIn this readme and the package documentation, these are the definitions of\ncommonly used terms:\n\n* \"converter\": function that changes an item's type.\n* \"modifier\": function that changes an item, but not its type\n(although, in a couple cases, a `modifier` will produce more than one of the original type).\n* \"transformer\": either a \"converter\" or \"modifier\".\n\n### General vs Specific Tools\n\n`modify` uses Python's [`singledispatch`](https://peps.python.org/pep-0443/) system. That means you can call the\ngeneral function for transformation and it will call the\nappropriate function based on the type of the first positional argument\npassed.[^1]\n\nAlternatively, every function called by `modify`'s dispatchers is also callable\ndirectly using a straightforward syntax. For example,\nto add a string prefix to every item in a `list` (or `list`-like object), you could call:\n\n```python\nadd_prefix(your_list, prefix, divider) # divider is optional\n```\n\nor:\n\n```python\nadd_prefix_to_list(your_list, prefix, divider) # divider is optional\n```\n\nThe dispatchers are just a convenience for shorter calls and require you to\nremember less verbiage. However, the specific functions are also included for\neffectuate greater\nreliability and clarity in your code.\n\n### Dispatchers\n\nThe table below outlines the functionality of the general transformers (dispatchers),\nwhat types they support, and whether there is a recursive option for applying\nthe function to nested objects as well.\n\n| name | effect | supported types (including generic equivalents) | recursive parameter |\n| --- | --- | --- | --- |\n| `add_prefix` | Adds `prefix` to `item` with optional `divider` | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `add_suffix` | Adds `suffix` to `item` with optional `divider` | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `capitalify` | Changes text to capital case | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `cleave` | Divides 1 object into 2 objects | `dict`, `list`, `str`, `tuple` | |\n| `drop_dunders` | Drops items that begin with 2 underscores | `dict`, `list`, `object`, `str`, `tuple` | |\n| `drop_duplicates` | Drops duplicate items | `list`, `str`, `tuple` | |\n| `drop_dunders` | Drops items that begin with at least 1 underscore | `dict`, `list`, `object`, `str`, `tuple` | |\n| `drop_prefix` | Drops `suffix` from `item` with optional `divider` | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `drop_substring` |  Drops `substring` from `item` | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `drop_suffix` | Adds `suffix` from `item` with optional `divider` | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n| `separate` | Divides 1 object into *n* objects | `dict`, `list`, `str`, `tuple` | |\n| `snakify` | Changes text to snake case | `dict`, `list`, `set`, `str`, `tuple` | ✅ |\n\nYou should feel confident using the general transformers as long as you pass a\nsupported type or its generic equivalent (e.g. `MutableMapping` for `dict`). The\nonly limitations would be if you have created a custom class that appears as\nmultiple types or masks its underlying type. There are also a few specific\nfunctions (e.g. `add_slots` for `dataclasses`) for which there is no general\ntransformer because only one datatype is possible. Nonetheless, `modify` supports\ndirect access to all of the specific transformers used (rather than making them\nanonymous functions as most uses of dispatching do).\n\n### Specific Transformers\n\nEach specific tool in `modify` follows a common syntax, outlined below:\n\n| | `dict` | `list` | `object` | `set` | `str` | `tuple` | `values` |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| `add_prefix_to_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `add_slots_` | | | ✅ | | | | |\n| `add_suffix_to_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `capitalify_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `cleave_` | ✅ | ✅ | | | ✅ | ✅ | ✅ |\n| `drop_dunders_from_` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n| `drop_duplicates_from_` | | ✅ | | | ✅ | ✅ | |\n| `drop_prefix_from_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `drop_privates_from_` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n| `drop_substring_from_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `drop_suffix_from_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n| `separate_` | ✅ | ✅ | | | ✅ | ✅ | ✅ |\n| `snakify_` | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |\n\nThe `dict` suffix to function names refers to the keys of a `dict`-like object.\n`values` refers to the values of a `dict`-like object. If the related dispatcher\nidentifies a passed item as a MutableMapping, the `dict` (and not `values`)\nfunction is called. Thus, changing values in a `dict`-like objects is the one\ninstance when you must call the specific transformer instead of the general one.\n\n`object`, as a suffix is inclusive of any class, instance, or module other than\nthe other listed types. This is because many of the same underlying commands\n(such as `getattr` work in the same manner across those data types).\n\n## Contributing\n\nContributors are always welcome. Feel free to grab an [issue](https://www.github.com/WithPrecedent/modify/issues) to work on or make a suggested improvement. If you wish to contribute, please read the [Contribution Guide](https://www.github.com/WithPrecedent/modify/contributing.md) and [Code of Conduct](https://www.github.com/WithPrecedent/modify/code_of_conduct.md).\n\n## Similar Projects\n\n* **`itertools`**:\n* **`more-itertools`**:\n\n## Acknowledgments\n\nI would like to thank the University of Kansas School of Law for tolerating and\nsupporting this law professor's coding efforts, an endeavor which is well\noutside the typical scholarly activities in the discipline.\n\n## License\n\nUse of this repository is authorized under the [Apache Software License 2.0](https://www.github.com/WithPrecedent/modify/blog/main/LICENSE).\n\n[^1]: Python's `singlddispatch` only supports dispatching based on the first\n    positional argument. Because `modify` was designed to be lightweight, it uses\n    this limited system rather than relying on a more sophisticated dispatching package.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithprecedent%2Fnaru","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwithprecedent%2Fnaru","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithprecedent%2Fnaru/lists"}