{"id":4677,"library":"patch","title":"Python Patch","description":"The `patch` library (version 1.16) is a Python utility designed to parse and apply unified diffs. It functions both as a command-line tool and a library for programmatic use, enabling developers to integrate patch application into their Python applications. The project's last release was in 2016, indicating a low or inactive release cadence, with a fork (`patch-ng`) emerging due to the original project's limited maintenance.","status":"maintenance","version":"1.16","language":"python","source_language":"en","source_url":"https://github.com/techtonik/python-patch/","tags":["diff","patch","unified-diff","version control","code changes"],"install":[{"cmd":"pip install patch","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"Used for representing a collection of patches and applying them.","symbol":"PatchSet","correct":"from patch import PatchSet"},{"note":"Function to parse a unified diff from a string.","symbol":"fromstring","correct":"from patch import fromstring"},{"note":"Function to parse a unified diff from a file.","symbol":"fromfile","correct":"from patch import fromfile"}],"quickstart":{"code":"import os\nimport tempfile\nfrom patch import fromstring, PatchSet\n\n# Create a dummy original file\noriginal_content = \"\"\"Line 1\nLine 2\nLine 3\n\"\"\"\nwith tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix='.txt') as f_orig:\n    f_orig.write(original_content)\n    original_filepath = f_orig.name\n\n# Create a diff that adds a line and modifies another\ndiff_content = \"\"\"--- a/test.txt\t2023-01-01 00:00:00.000000000 +0000\n+++ b/test.txt\t2023-01-01 00:00:00.000000000 +0000\n@@ -1,3 +1,4 @@\n Line 1 modified\n+Line 1.5 added\n Line 2\n Line 3\n\"\"\"\n\n# Parse the diff\npatch_set = fromstring(diff_content)\n\n# Apply the patch to the original file\n# The library assumes the files are in the current working directory\n# or specified by path. Here, we'll patch a file named 'test.txt'\n# which we'll simulate by reading from original_filepath and applying to a new file.\n\ntarget_filename = os.path.basename(original_filepath)\n\n# To apply, the patch expects the target file to exist at a specific relative path.\n# We will simulate this by copying our temp file and then patching that copy.\n\npatched_content = None\nwith open(original_filepath, 'r') as f_read:\n    original_lines = f_read.readlines()\n\n# Manually apply the patch (as the library's apply() method typically writes to disk)\n# For a quickstart, it's easier to show the logic.\n\n# In a real scenario, you'd do: patch_set.apply(strip=0, root=os.path.dirname(original_filepath))\n# But it requires writing to the same filename specified in the diff.\n\n# Let's write the original content to a file that matches the diff's target name\nwith open(target_filename, 'w') as f_target:\n    f_target.write(original_content)\n\n# Now, apply the patch using the library's method\n# The apply method attempts to write back to the file system.\nsuccess = patch_set.apply(strip=0, root='.') # root is current dir where target_filename is\n\nif success:\n    with open(target_filename, 'r') as f_patched:\n        patched_content = f_patched.read()\n    print(\"Patch applied successfully.\")\n    print(\"Patched content:\\n\", patched_content)\nelse:\n    print(\"Failed to apply patch.\")\n\n# Cleanup temporary files\nos.remove(original_filepath)\nos.remove(target_filename)\n","lang":"python","description":"This quickstart demonstrates how to programmatically apply a unified diff to a file. It creates a temporary original file, defines a diff string, parses the diff using `fromstring`, and then applies it to a simulated target file. Note that the `apply` method modifies files on the filesystem."},"warnings":[{"fix":"Consider using the `patch-ng` library, which is a community fork actively maintained and compatible with Python 3.6+. `pip install \"patch-ng\"`","message":"The `patch` library (techtonik/python-patch) has not seen an official release since February 2016 (version 1.16). This suggests it is largely unmaintained. Users seeking active development and support should consider alternatives or forks.","severity":"deprecated","affected_versions":"<=1.16"},{"fix":"When declaring `patch` as a dependency, use strict version specifiers like `patch==1.*` to prevent unintended upgrades to a potentially breaking 2.x release.","message":"The library documentation explicitly warns against future API breaks. If a version 2.x were ever released, it is expected to introduce breaking changes.","severity":"breaking","affected_versions":"All versions 1.x (regarding potential future 2.x)"},{"fix":"Ensure you import from `patch` (for diffs) or `unittest.mock` (for testing mocks) as appropriate for your task.","message":"This `patch` library is distinct from `unittest.mock.patch`, which is part of Python's standard library for testing and mocking objects. Confusing the two can lead to incorrect usage and debugging challenges.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For complex patching scenarios involving file system changes beyond content modification or non-unified diffs, alternative tools or manual pre/post-processing may be required.","message":"The library has known limitations; it does not support file renaming, creation, or removal, directory tree operations, version control specific properties, or non-unified diff formats.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.16':7 '2016':51 'appli':16 'applic':39,43 'cadenc':58 'chang':82 'code':81 'command':25 'command-lin':24 'control':80 'design':12 'develop':35 'diff':18,74,78 'due':66 'emerg':65 'enabl':34 'fork':61 'function':20 'inact':56 'indic':52 'integr':37 'last':47 'librari':5,30 'limit':72 'line':26 'low':54 'mainten':73 'ng':64 'origin':69 'pars':14 'patch':2,4,38,63,75 'patch-ng':62 'programmat':32 'project':45,70 'python':1,10,42 'releas':48,57 'tool':27 'unifi':17,77 'unified-diff':76 'use':33 'util':11 'version':6,79","created_at":"2026-04-12T14:02:53.377673+00:00","updated_at":"2026-04-16T17:54:30.550725+00:00","problems":[{"fix":"Install the library using pip: `pip install \"patch==1.*\"` or ensure the `patch.py` file is in your project directory or Python path if using it as a standalone script.","cause":"The `patch` library is not installed in your Python environment or is not accessible via the Python path.","error":"ModuleNotFoundError: No module named 'patch'"},{"fix":"Execute the script explicitly with Python: `python -m patch <your_patch_file>` (if installed) or `python patch.py <your_patch_file>` (if using the standalone script).","cause":"This error occurs when attempting to run the `patch` library as a command-line tool without properly invoking the Python interpreter, or if the `patch.py` script (or its executable wrapper) is not in a directory included in your system's PATH.","error":"'patch' is not recognized as an internal or external command"},{"fix":"Manually inspect the diff and the original file to identify the discrepancies. You may need to edit the patch file, the target file, or apply the changes manually. This error can also occur if the patch tries to perform unsupported operations like file renaming, creation, or directory operations, or if the diff format is not unified.","cause":"This message indicates that the `patch` tool could not apply a specific section (hunk) of the diff to the target file, usually because the target file's content doesn't exactly match what the patch expects.","error":"Hunk #X failed at Y"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.16","cli_name":"patch","cli_version":"sh: 1: patch: not found","type":"library","homepage":null,"github":"https://github.com/techtonik/python-patch","docs":null,"changelog":null,"pypi":"https://pypi.org/project/patch/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-30","next_check":"2026-07-28","install_tag":null}}