Skip to main content
https://img.shields.io/github/actions/workflow/status/adamchainz/unipatch/main.yml.svg?branch=main&style=for-the-badge https://img.shields.io/badge/Coverage-100%25-success?style=for-the-badge https://img.shields.io/pypi/v/unipatch.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

Apply unified diffs in memory, compatible with GNU patch.

A quick example:

>>> import textwrap
>>> import unipatch
>>> patch = textwrap.dedent(
...     """\
...     @@ -1,2 +1,3 @@
...      apples
...      bananas
...     +cherries
...     """
... )
>>> print(unipatch.apply_patch("apples\nbananas\n", patch))
apples
bananas
cherries

Installation

Use pip:

python -m pip install unipatch

Python 3.10 to 3.15 supported.

API

apply_patch(source: str, patch: str, forwards: bool=True)

Apply the unified diff in the string patch to the string source and return the resulting string. Pass forwards=False to apply the patch in reverse, undoing it instead.

Raises PatchError if the patch cannot be parsed or does not apply.

>>> unipatch.apply_patch("a\nb\n", "@@ -1 +1 @@\n-a\n+c\n")
'c\nb\n'
>>> unipatch.apply_patch("c\nb\n", "@@ -1 +1 @@\n-a\n+c\n", forwards=False)
'a\nb\n'

PatchError

The base exception class, a subclass of ValueError. It has two subclasses:

  • PatchParseError: the patch is not valid unified diff format.

  • HunkApplyError: the patch parsed, but a hunk’s lines do not match the source.

Exception messages name the failing hunk and what went wrong.

Behaviour

unipatch follows the behaviour of the GNU patch commandline utility, verified by differentially testing against it with randomized inputs:

  • Hunks may apply at an offset from the line numbers stated in their @@ headers, matching by content, with a found offset carrying forward to later hunks.

  • A fuzz factor ignores up to two mismatching context lines at the edges of a hunk. Ignored context lines are left as they are in the source. A hunk with less context on one side, as diff produces at the start or end of a file, only applies at that edge of the source.

  • Oddities are tolerated like GNU patch:

    • Hunks cut short at the end of the patch

    • Context lines that have lost their leading space (empty and tab-led lines)

    • \ No newline at end of file markers

Only unified diff format is supported, not the older context or ed formats. Hence the name is unipatch.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unipatch-1.0.0.tar.gz (8.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unipatch-1.0.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file unipatch-1.0.0.tar.gz.

File metadata

  • Download URL: unipatch-1.0.0.tar.gz
  • Upload date:
  • Size: 8.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for unipatch-1.0.0.tar.gz
Algorithm Hash digest
SHA256 993df2fe49f8114a95eaaf088ecf498c0dd20a8387caa17d63e8d1c29ea50af1
MD5 dd4d4f713822faea60f3a7c7acd5cc50
BLAKE2b-256 0dda2a8884bb5aa2ab8012737710b85f5bae6df14bf5175742a30bf394a36560

See more details on using hashes here.

Provenance

The following attestation bundles were made for unipatch-1.0.0.tar.gz:

Publisher: main.yml on adamchainz/unipatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file unipatch-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: unipatch-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for unipatch-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 195ac3110766c744e029239aba82b287041fc9fd703b062e6574cc9681f1b6c9
MD5 03632bc162664b24688ed68dfc34aefa
BLAKE2b-256 64a375c32ba2b157f56e2842fa2d48a85e1cee75fd670698dd7bfd18dd73990c

See more details on using hashes here.

Provenance

The following attestation bundles were made for unipatch-1.0.0-py3-none-any.whl:

Publisher: main.yml on adamchainz/unipatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page