{ "info": { "author": "Christopher S. Corley", "author_email": "cscorley@crimson.ua.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Version Control", "Topic :: Text Processing" ], "description": "What The Patch!?\n================\n\n.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat\n :target: https://travis-ci.org/cscorley/whatthepatch\n\nWhat The Patch!? is a library for both parsing and applying patch files.\n\nFeatures\n---------\n\n- Parsing of almost all ``diff`` formats (except forwarded ed):\n\n - normal (default, --normal)\n - copied context (-c, --context)\n - unified context (-u, --unified)\n - ed script (-e, --ed)\n - rcs ed script (-n, --rcs)\n\n- Parsing of several SCM patches:\n\n - CVS\n - SVN\n - Git\n\nInstallation\n------------\n\nTo install What The Patch!?, simply:\n\n.. code-block:: bash\n\n $ pip install whatthepatch\n\nUsage\n=====\n\nLet us say we have a patch file containing some changes, aptly named\n'somechanges.patch':\n\n.. code-block:: diff\n\n --- lao\t2012-12-26 23:16:54.000000000 -0600\n +++ tzu\t2012-12-26 23:16:50.000000000 -0600\n @@ -1,7 +1,6 @@\n -The Way that can be told of is not the eternal Way;\n -The name that can be named is not the eternal name.\n The Nameless is the origin of Heaven and Earth;\n -The Named is the mother of all things.\n +The named is the mother of all things.\n +\n Therefore let there always be non-being,\n so we may see their subtlety,\n And let there always be being,\n @@ -9,3 +8,6 @@\n The two are the same,\n But after they are produced,\n they have different names.\n +They both may be called deep and profound.\n +Deeper and more profound,\n +The door of all subtleties!\n\n\nParsing\n-------\n\nHere is how we would use What The Patch!? in Python to get the changeset for\neach diff in the patch:\n\n.. code-block:: python\n\n >>> import whatthepatch\n >>> import pprint\n >>> with open('tests/casefiles/diff-unified.diff') as f:\n ... text = f.read()\n ...\n >>> for diff in whatthepatch.parse_patch(text):\n ... print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n ...\n diff(header=header(index_path=None,\n old_path='lao',\n old_version='2013-01-05 16:56:19.000000000 -0600',\n new_path='tzu',\n new_version='2013-01-05 16:56:35.000000000 -0600'),\n changes=[Change(old=1, new=None, hunk=1, line='The Way that can be told of is not the eternal Way;'),\n Change(old=2, new=None, hunk=1, line='The name that can be named is not the eternal name.'),\n Change(old=3, new=1, hunk=1, line='The Nameless is the origin of Heaven and Earth;'),\n Change(old=4, new=None, hunk=1, line='The Named is the mother of all things.'),\n Change(old=None, new=2, hunk=1, line='The named is the mother of all things.'),\n Change(old=None, new=3, hunk=1, line=''), Change(old=5, new=4, hunk=1, line='Therefore let there always be non-being,'),\n Change(old=6, new=5, hunk=1, line=' so we may see their subtlety,'),\n Change(old=7, new=6, hunk=1, line='And let there always be being,'),\n Change(old=9, new=8, hunk=2, line='The two are the same,'),\n Change(old=10, new=9, hunk=2, line='But after they are produced,'),\n Change(old=11, new=10, hunk=2, line=' they have different names.'),\n Change(old=None, new=11, hunk=2, line='They both may be called deep and profound.'),\n Change(old=None, new=12, hunk=2, line='Deeper and more profound,'),\n Change(old=None, new=13, hunk=2, line='The door of all subtleties!')],\n text='...')\n\nThe changes are listed as they are in the patch, but instead of the +/- syntax\nof the patch, we get a tuple of two numbers and the text of the line.\nWhat these numbers indicate are as follows:\n\n#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was **removed**.\n#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was **inserted**.\n#. ``( old=5, new=4, ... )`` indicates that line 5 of lao and line 4 of tzu are **equal**.\n\nPlease note that not all patch formats provide the actual lines modified, so some \nresults will have the text portion of the tuple set to ``None``.\n\nApplying\n--------\n\nTo apply a diff to some lines of text, first read the patch and parse it.\n\n.. code-block:: python\n\n >>> import whatthepatch\n >>> with open('tests/casefiles/diff-default.diff') as f:\n ... text = f.read()\n ...\n >>> with open('tests/casefiles/lao') as f:\n ... lao = f.read()\n ...\n >>> diff = [x for x in whatthepatch.parse_patch(text)]\n >>> diff = diff[0]\n >>> tzu = whatthepatch.apply_diff(diff, lao)\n >>> tzu # doctest: +NORMALIZE_WHITESPACE\n ['The Nameless is the origin of Heaven and Earth;',\n 'The named is the mother of all things.',\n '',\n 'Therefore let there always be non-being,',\n ' so we may see their subtlety,',\n 'And let there always be being,',\n ' so we may see their outcome.',\n 'The two are the same,',\n 'But after they are produced,',\n ' they have different names.',\n 'They both may be called deep and profound.',\n 'Deeper and more profound,',\n 'The door of all subtleties!']\n\n\nContribute\n==========\n\n#. Fork this repository\n#. Create a new branch to work on\n#. Commit your tests and/or changes\n#. Push and create a pull request here!\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cscorley/whatthepatch", "keywords": "patch", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "whatthepatch-graingert", "package_url": "https://pypi.org/project/whatthepatch-graingert/", "platform": "", "project_url": "https://pypi.org/project/whatthepatch-graingert/", "project_urls": { "Homepage": "https://github.com/cscorley/whatthepatch" }, "release_url": "https://pypi.org/project/whatthepatch-graingert/0.0.6/", "requires_dist": null, "requires_python": "", "summary": "A patch parsing library.", "version": "0.0.6" }, "last_serial": 2768729, "releases": { "0.0.5": [ { "comment_text": "", "digests": { "md5": "713a2750aadb41a235209acd3cffafa1", "sha256": "c3d11302583add7becd2b4e8fb126b59064d42abceea9ead79a0fffb4afcbf8a" }, "downloads": -1, "filename": "whatthepatch_graingert-0.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "713a2750aadb41a235209acd3cffafa1", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 12885, "upload_time": "2017-04-10T20:25:03", "url": "https://files.pythonhosted.org/packages/ab/24/90fd206598f06181b6cdbfdb67dcc0d9327c210334f74ca06f968475f4b9/whatthepatch_graingert-0.0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8d57ab0b95fb3b355bf41d16a19d7398", "sha256": "a7643be700dbb127c6bf506fc99e8123c447c394454c538e23624a35e10c370f" }, "downloads": -1, "filename": "whatthepatch-graingert-0.0.5.tar.gz", "has_sig": false, "md5_digest": "8d57ab0b95fb3b355bf41d16a19d7398", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10215, "upload_time": "2017-04-10T20:25:01", "url": "https://files.pythonhosted.org/packages/da/7b/fc1c89abc346104941ae58dd5c3739bf2df27ffa0384e0c3b37e5e726f2d/whatthepatch-graingert-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "d2911a91b1d44c9908de99d0d97baeac", "sha256": "d921cff0fc4c49ff36426ef3d2bc0e3e643c91e7796e8ac62ec1c239262356ec" }, "downloads": -1, "filename": "whatthepatch_graingert-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d2911a91b1d44c9908de99d0d97baeac", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 12944, "upload_time": "2017-04-10T20:43:33", "url": "https://files.pythonhosted.org/packages/04/7f/915a4a6711a317ca0e9ed6298b56b3fe553b9f2c5d245eff380d381f9ed7/whatthepatch_graingert-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e7fdbe06548f4042d11c3943015914a6", "sha256": "6bb6a682e808ccde811181422604068a0cbbad0accb9619c3b63c4da470741fe" }, "downloads": -1, "filename": "whatthepatch-graingert-0.0.6.tar.gz", "has_sig": false, "md5_digest": "e7fdbe06548f4042d11c3943015914a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10276, "upload_time": "2017-04-10T20:43:31", "url": "https://files.pythonhosted.org/packages/ee/e8/c6fae312ea10dd065a7d4ea848e1f35c51b47d5215ad3ccd104d1144745a/whatthepatch-graingert-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d2911a91b1d44c9908de99d0d97baeac", "sha256": "d921cff0fc4c49ff36426ef3d2bc0e3e643c91e7796e8ac62ec1c239262356ec" }, "downloads": -1, "filename": "whatthepatch_graingert-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d2911a91b1d44c9908de99d0d97baeac", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 12944, "upload_time": "2017-04-10T20:43:33", "url": "https://files.pythonhosted.org/packages/04/7f/915a4a6711a317ca0e9ed6298b56b3fe553b9f2c5d245eff380d381f9ed7/whatthepatch_graingert-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e7fdbe06548f4042d11c3943015914a6", "sha256": "6bb6a682e808ccde811181422604068a0cbbad0accb9619c3b63c4da470741fe" }, "downloads": -1, "filename": "whatthepatch-graingert-0.0.6.tar.gz", "has_sig": false, "md5_digest": "e7fdbe06548f4042d11c3943015914a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10276, "upload_time": "2017-04-10T20:43:31", "url": "https://files.pythonhosted.org/packages/ee/e8/c6fae312ea10dd065a7d4ea848e1f35c51b47d5215ad3ccd104d1144745a/whatthepatch-graingert-0.0.6.tar.gz" } ] }