Library to parse and apply unified diffs. `patch-ng` is a fork of the original `python-patch` project, providing active maintenance and bug fixes. The current version is 1.19.0, released in October 2025. It is actively maintained by Conan-io with regular releases and is compatible with Python 3.6+.
Install & Compatibility
Where this runs
tested against v1.19.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
from patch_ng import PatchSet
from patch_ng import fromfile
from patch_ng import Hunk
This example demonstrates how to create a simple text file, define a unified diff patch as a string, parse it using `from_string`, and then apply the patch to the file within a temporary directory using `patchset.apply()`.
import os
import tempfile
import shutil
from patch_ng import from_string, PatchSet
# Create a temporary directory to work in
temp_dir = tempfile.mkdtemp()
original_file_path = os.path.join(temp_dir, "my_file.txt")
try:
# 1. Create an original file
with open(original_file_path, "w") as f:
f.write("Line 1: Hello world\n")
f.write("Line 2: This is a test.\n")
f.write("Line 3: End of file.\n")
print(f"Original file '{os.path.basename(original_file_path)}' created in {temp_dir}:\n" \
f"{open(original_file_path, 'r').read()}")
# 2. Define a unified diff patch string
# This patch changes 'Line 2' and adds 'New Line 2.5'
patch_content = """--- a/my_file.txt
+++ b/my_file.txt
@@ -1,3 +1,4 @@
Line 1: Hello world
-Line 2: This is a test.
+Line 2: This line was changed.
+New Line 2.5: Inserted line.
Line 3: End of file.
"""
# 3. Parse the patch string
# The `strip` argument removes leading path components (e.g., 'a/' or 'b/')
patchset = from_string(patch_content)
if not patchset:
print("Failed to parse patch content.")
else:
# 4. Apply the patch to the specified root directory
# The `root` argument is crucial to apply the patch outside the current working directory.
success = patchset.apply(strip=1, root=temp_dir)
if success:
print(f"Patch applied successfully to files in {temp_dir}.")
print(f"\nPatched file content of '{os.path.basename(original_file_path)}':\n" \
f"{open(original_file_path, 'r').read()}")
else:
print("Failed to apply patch.")
finally:
# Clean up the temporary directory
shutil.rmtree(temp_dir)
print(f"\nCleaned up temporary directory: {temp_dir}")
Upgrade
Version history
Breaking-change detection hasn't run for this library yet.
Audit
Security & dependencies
CVE tracking and dependency tree are planned for a later release.