{"id":13825641,"url":"https://github.com/clarketm/mergedeep","last_synced_at":"2025-04-12T22:28:25.029Z","repository":{"id":34076927,"uuid":"169014362","full_name":"clarketm/mergedeep","owner":"clarketm","description":"A deep merge function for 🐍.","archived":false,"fork":false,"pushed_at":"2024-04-02T15:47:12.000Z","size":97,"stargazers_count":154,"open_issues_count":11,"forks_count":12,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-04T02:08:06.551Z","etag":null,"topics":["deepmerge","mapping","merge","mergedeep","python"],"latest_commit_sha":null,"homepage":"https://mergedeep.readthedocs.io/en/latest/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clarketm.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":"2019-02-04T01:30:45.000Z","updated_at":"2025-03-28T16:07:00.000Z","dependencies_parsed_at":"2024-05-29T15:07:40.067Z","dependency_job_id":null,"html_url":"https://github.com/clarketm/mergedeep","commit_stats":{"total_commits":38,"total_committers":5,"mean_commits":7.6,"dds":"0.13157894736842102","last_synced_commit":"b52fae95fb612a75c57182706294a26c81698621"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarketm%2Fmergedeep","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarketm%2Fmergedeep/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarketm%2Fmergedeep/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clarketm%2Fmergedeep/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clarketm","download_url":"https://codeload.github.com/clarketm/mergedeep/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248639255,"owners_count":21137811,"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":["deepmerge","mapping","merge","mergedeep","python"],"created_at":"2024-08-04T09:01:24.648Z","updated_at":"2025-04-12T22:28:25.003Z","avatar_url":"https://github.com/clarketm.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# [mergedeep](https://mergedeep.readthedocs.io/en/latest/)\n\n[![PyPi release](https://img.shields.io/pypi/v/mergedeep.svg)](https://pypi.org/project/mergedeep/)\n[![PyPi versions](https://img.shields.io/pypi/pyversions/mergedeep.svg)](https://pypi.org/project/mergedeep/)\n[![Downloads](https://pepy.tech/badge/mergedeep)](https://pepy.tech/project/mergedeep)\n[![Conda Version](https://img.shields.io/conda/vn/conda-forge/mergedeep.svg)](https://anaconda.org/conda-forge/mergedeep)\n[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/mergedeep.svg)](https://anaconda.org/conda-forge/mergedeep)\n[![Documentation Status](https://readthedocs.org/projects/mergedeep/badge/?version=latest)](https://mergedeep.readthedocs.io/en/latest/?badge=latest)\n\nA deep merge function for 🐍.\n\n[Check out the mergedeep docs](https://mergedeep.readthedocs.io/en/latest/)\n\n## Installation\n\n```bash\n$ pip install mergedeep\n```\n\n## Usage\n\n```text\nmerge(destination: MutableMapping, *sources: Mapping, strategy: Strategy = Strategy.REPLACE) -\u003e MutableMapping\n```\n\nDeep merge without mutating the source dicts.\n\n```python3\nfrom mergedeep import merge\n\na = {\"keyA\": 1}\nb = {\"keyB\": {\"sub1\": 10}}\nc = {\"keyB\": {\"sub2\": 20}}\n\nmerged = merge({}, a, b, c) \n\nprint(merged)\n# {\"keyA\": 1, \"keyB\": {\"sub1\": 10, \"sub2\": 20}}\n```\n\nDeep merge into an existing dict.\n```python3\nfrom mergedeep import merge\n\na = {\"keyA\": 1}\nb = {\"keyB\": {\"sub1\": 10}}\nc = {\"keyB\": {\"sub2\": 20}}\n\nmerge(a, b, c) \n\nprint(a)\n# {\"keyA\": 1, \"keyB\": {\"sub1\": 10, \"sub2\": 20}}\n```\n\n### Merge strategies:\n\n1. Replace (*default*)\n\n\u003e `Strategy.REPLACE`\n\n```python3\n# When `destination` and `source` keys are the same, replace the `destination` value with one from `source` (default).\n\n# Note: with multiple sources, the `last` (i.e. rightmost) source value will be what appears in the merged result. \n\nfrom mergedeep import merge, Strategy\n\ndst = {\"key\": [1, 2]}\nsrc = {\"key\": [3, 4]}\n\nmerge(dst, src, strategy=Strategy.REPLACE) \n# same as: merge(dst, src)\n\nprint(dst)\n# {\"key\": [3, 4]}\n```\n\n2. Additive\n\n\u003e `Strategy.ADDITIVE`\n\n```python3\n# When `destination` and `source` values are both the same additive collection type, extend `destination` by adding values from `source`.\n# Additive collection types include: `list`, `tuple`, `set`, and `Counter`\n\n# Note: if the values are not additive collections of the same type, then fallback to a `REPLACE` merge.\n\nfrom mergedeep import merge, Strategy\n\ndst = {\"key\": [1, 2], \"count\": Counter({\"a\": 1, \"b\": 1})}\nsrc = {\"key\": [3, 4], \"count\": Counter({\"a\": 1, \"c\": 1})}\n\nmerge(dst, src, strategy=Strategy.ADDITIVE) \n\nprint(dst)\n# {\"key\": [1, 2, 3, 4], \"count\": Counter({\"a\": 2, \"b\": 1, \"c\": 1})}\n```\n\n3. Typesafe replace\n\n\u003e `Strategy.TYPESAFE_REPLACE` or `Strategy.TYPESAFE`\n\n```python3\n# When `destination` and `source` values are of different types, raise `TypeError`. Otherwise, perform a `REPLACE` merge.\n\nfrom mergedeep import merge, Strategy\n\ndst = {\"key\": [1, 2]}\nsrc = {\"key\": {3, 4}}\n\nmerge(dst, src, strategy=Strategy.TYPESAFE_REPLACE) # same as: `Strategy.TYPESAFE`  \n# TypeError: destination type: \u003cclass 'list'\u003e differs from source type: \u003cclass 'set'\u003e for key: \"key\"\n```\n\n4. Typesafe additive\n\n\u003e `Strategy.TYPESAFE_ADDITIVE`\n\n```python3\n# When `destination` and `source` values are of different types, raise `TypeError`. Otherwise, perform a `ADDITIVE` merge.\n\nfrom mergedeep import merge, Strategy\n\ndst = {\"key\": [1, 2]}\nsrc = {\"key\": {3, 4}}\n\nmerge(dst, src, strategy=Strategy.TYPESAFE_ADDITIVE) \n# TypeError: destination type: \u003cclass 'list'\u003e differs from source type: \u003cclass 'set'\u003e for key: \"key\"\n```\n\n## License\n\nMIT \u0026copy; [**Travis Clarke**](https://blog.travismclarke.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarketm%2Fmergedeep","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclarketm%2Fmergedeep","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclarketm%2Fmergedeep/lists"}