Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

What The Patch!?

Note that this is a fork of [whatthepatch](https://github.com/cscorley/whatthepatch) and aims to add pydantic support

What The Patch!? is a library for both parsing and applying patch files.

Status

https://github.com/cscorley/whatthepatch/workflows/Build/badge.svg

This has been released as 1.0, but has never had much active development. The functions are stable and have been reliable for several years, even if they are not ideally implemented. Pull requests will always be considered, merged, and released; however, issues may not ever be fixed by the maintainer.

Contribute

  1. Fork this repository

  2. Create a new branch to work on

  3. Commit your tests and/or changes

  4. Push and create a pull request here!

Features

  • Parsing of almost all diff formats (except forwarded ed):

    • normal (default, –normal)

    • copied context (-c, –context)

    • unified context (-u, –unified)

    • ed script (-e, –ed)

    • rcs ed script (-n, –rcs)

  • Parsing of several SCM patches:

    • CVS

    • SVN

    • Git

Installation

This library is available on PyPI and can be installed via pip:

$ pip install whatthepatch

Usage

Let us say we have a patch file containing some changes, aptly named ‘somechanges.patch’:

--- lao     2012-12-26 23:16:54.000000000 -0600
+++ tzu     2012-12-26 23:16:50.000000000 -0600
@@ -1,7 +1,6 @@
-The Way that can be told of is not the eternal Way;
-The name that can be named is not the eternal name.
 The Nameless is the origin of Heaven and Earth;
-The Named is the mother of all things.
+The named is the mother of all things.
+
 Therefore let there always be non-being,
   so we may see their subtlety,
  And let there always be being,
@@ -9,3 +8,6 @@
 The two are the same,
 But after they are produced,
   they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!

Parsing

Here is how we would use What The Patch!? in Python to get the changeset for each diff in the patch:

>>> import whatthepatch
>>> import pprint
>>> with open('tests/casefiles/diff-unified.diff') as f:
...     text = f.read()
...
>>> for diff in whatthepatch.parse_patch(text):
...     print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
...
diff(header=header(index_path=None,
                   old_path='lao',
                   old_version='2013-01-05 16:56:19.000000000 -0600',
                   new_path='tzu',
                   new_version='2013-01-05 16:56:35.000000000 -0600'),
     changes=[Change(old=1, new=None, line='The Way that can be told of is not the eternal Way;', hunk=1),
              Change(old=2, new=None, line='The name that can be named is not the eternal name.', hunk=1),
              Change(old=3, new=1, line='The Nameless is the origin of Heaven and Earth;', hunk=1),
              Change(old=4, new=None, line='The Named is the mother of all things.', hunk=1),
              Change(old=None, new=2, line='The named is the mother of all things.', hunk=1),
              Change(old=None, new=3, line='', hunk=1),
              Change(old=5, new=4, line='Therefore let there always be non-being,', hunk=1),
              Change(old=6, new=5, line='  so we may see their subtlety,', hunk=1),
              Change(old=7, new=6, line='And let there always be being,', hunk=1),
              Change(old=9, new=8, line='The two are the same,', hunk=2),
              Change(old=10, new=9, line='But after they are produced,', hunk=2),
              Change(old=11, new=10, line='  they have different names.', hunk=2),
              Change(old=None, new=11, line='They both may be called deep and profound.', hunk=2),
              Change(old=None, new=12, line='Deeper and more profound,', hunk=2),
              Change(old=None, new=13, line='The door of all subtleties!', hunk=2)],
     text='...')

The changes are listed as they are in the patch, but instead of the +/- syntax of the patch, we get a tuple of two numbers and the text of the line. What these numbers indicate are as follows:

  1. ( old=1, new=None, ... ) indicates line 1 of the file lao was removed.

  2. ( old=None, new=2, ... ) indicates line 2 of the file tzu was inserted.

  3. ( old=5, new=4, ... ) indicates that line 5 of lao and line 4 of tzu are equal.

Please note that not all patch formats provide the actual lines modified, so some results will have the text portion of the tuple set to None.

Applying

To apply a diff to some lines of text, first read the patch and parse it.

>>> import whatthepatch
>>> with open('tests/casefiles/diff-default.diff') as f:
...     text = f.read()
...
>>> with open('tests/casefiles/lao') as f:
...     lao = f.read()
...
>>> diff = [x for x in whatthepatch.parse_patch(text)]
>>> diff = diff[0]
>>> tzu = whatthepatch.apply_diff(diff, lao)
>>> tzu  # doctest: +NORMALIZE_WHITESPACE
['The Nameless is the origin of Heaven and Earth;',
 'The named is the mother of all things.',
 '',
 'Therefore let there always be non-being,',
 '  so we may see their subtlety,',
 'And let there always be being,',
 '  so we may see their outcome.',
 'The two are the same,',
 'But after they are produced,',
 '  they have different names.',
 'They both may be called deep and profound.',
 'Deeper and more profound,',
 'The door of all subtleties!']

If apply does not satisfy your needs and you are on a system that has patch in PATH, you can also call apply_diff(diff, lao, use_patch=True). The default is false, and patch is not necessary to apply diffs to text.

Metadata

Release files for whatthepatch-pydantic 1.0.6a3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for whatthepatch-pydantic 1.0.6a3
File Size Uploaded
whatthepatch_pydantic-1.0.6a3.tar.gz 32.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for whatthepatch-pydantic 1.0.6a3
File Interpreter ABI Platform
whatthepatch_pydantic-1.0.6a3-py3-none-any.whl Python 3 none any Details

Total release size: 45.3 kB

Release files / whatthepatch_pydantic-1.0.6a3.tar.gz

Download URL whatthepatch_pydantic-1.0.6a3.tar.gz
Size 32.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d47ecfb272bca87f45b3f0e6058616a7f4bb1b81d6a7d5caa3ffaf51c2b89dfc
BLAKE2b-256 checksum
How to use checksums
282e31e87522f0e7d84e07fcd12ef943634426f6cf7ebcdeeaf1b7b8c7f3c464
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.12

Release files / whatthepatch_pydantic-1.0.6a3-py3-none-any.whl

Download URL whatthepatch_pydantic-1.0.6a3-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2e4d5fc24ad904ab2b2ab8e657948987fa464fa7f5031fdf5da37ae488c90643
BLAKE2b-256 checksum
How to use checksums
a064597ec9c9d2a427c2f410f4cc464919e103f900e6364a2f8105cec1f6936c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.12
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page