Hello community,

here is the log from the commit of package python-whatthepatch for 
openSUSE:Factory checked in at 2020-07-24 09:55:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-whatthepatch (Old)
 and      /work/SRC/openSUSE:Factory/.python-whatthepatch.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-whatthepatch"

Fri Jul 24 09:55:32 2020 rev:2 rq:822123 version:1.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-whatthepatch/python-whatthepatch.changes  
2019-08-13 13:25:36.953349679 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-whatthepatch.new.3592/python-whatthepatch.changes
        2020-07-24 09:57:56.977526773 +0200
@@ -1,0 +2,11 @@
+Tue Jul 21 13:05:20 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- update to 1.0.0
+  * Issue #26 fix where hardcoded "/tmp" reference was being used
+  * Support up to Python 3.8
+  * Drop support for Python 2, 3.4
+  * Bump Code of Conduct to 2.0
+- Add patch to build without nose:
+  * no-nose.patch
+
+-------------------------------------------------------------------

Old:
----
  whatthepatch-0.0.6.tar.gz

New:
----
  no-nose.patch
  whatthepatch-1.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-whatthepatch.spec ++++++
--- /var/tmp/diff_new_pack.DDYww3/_old  2020-07-24 09:58:02.125532082 +0200
+++ /var/tmp/diff_new_pack.DDYww3/_new  2020-07-24 09:58:02.129532086 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-whatthepatch
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,28 +12,30 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%define skip_python2 1
 Name:           python-whatthepatch
-Version:        0.0.6
+Version:        1.0.0
 Release:        0
-License:        MIT
 Summary:        A patch parsing and application library
-Url:            https://github.com/cscorley/whatthepatch
+License:        MIT
 Group:          Development/Languages/Python
+URL:            https://github.com/cscorley/whatthepatch
 Source:         
https://github.com/cscorley/whatthepatch/archive/%{version}.tar.gz#/whatthepatch-%{version}.tar.gz
-BuildRequires:  python-rpm-macros
+Patch0:         no-nose.patch
+BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools}
-BuildRequires:  %{python_module nose}
 BuildRequires:  ed
 BuildRequires:  fdupes
 BuildRequires:  patch
+BuildRequires:  python-rpm-macros
 Requires:       ed
 Requires:       patch
 BuildArch:      noarch
-
 %python_subpackages
 
 %description
@@ -41,6 +43,7 @@
 
 %prep
 %setup -q -n whatthepatch-%{version}
+%patch0 -p1
 
 %build
 %python_build
@@ -50,7 +53,7 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-%python_exec -m nose --with-doctest --doctest-extension=rst
+%pytest tests
 
 %files %{python_files}
 %doc README.rst

++++++ no-nose.patch ++++++
Index: whatthepatch-1.0.0/tests/test_apply.py
===================================================================
--- whatthepatch-1.0.0.orig/tests/test_apply.py
+++ whatthepatch-1.0.0/tests/test_apply.py
@@ -4,7 +4,7 @@ import whatthepatch as wtp
 from whatthepatch import exceptions
 from whatthepatch.snippets import which
 
-from nose.tools import assert_raises
+import pytest
 import unittest
 from unittest.case import SkipTest
 
@@ -26,7 +26,7 @@ class ApplyTestSuite(unittest.TestCase):
             self.lao = f.read().splitlines()
 
         with open("tests/casefiles/tzu") as f:
-            self.tzu = f.read().splitlines()
+           self.tzu = f.read().splitlines()
 
     def test_truth(self):
         self.assertEqual(type(self.lao), list)
@@ -59,10 +59,10 @@ class ApplyTestSuite(unittest.TestCase):
         with open("tests/casefiles/diff-unified-bad.diff") as f:
             diff_text = f.read()
 
-        with assert_raises(exceptions.ApplyException) as ec:
+        with pytest.raises(exceptions.ApplyException) as ec:
             _apply(self.lao, diff_text)
 
-        e = ec.exception
+        e = ec.value
         e_str = str(e)
         assert "line 4" in e_str
         assert "The Named is the mother of all tings." in e_str
@@ -73,10 +73,10 @@ class ApplyTestSuite(unittest.TestCase):
         with open("tests/casefiles/diff-unified-bad2.diff") as f:
             diff_text = f.read()
 
-        with assert_raises(exceptions.ApplyException) as ec:
+        with pytest.raises(exceptions.ApplyException) as ec:
             _apply(self.lao, diff_text)
 
-        e = ec.exception
+        e = ec.value
         e_str = str(e)
         assert "line 9" in e_str
         assert "The two are te same," in e_str
@@ -87,10 +87,10 @@ class ApplyTestSuite(unittest.TestCase):
         with open("tests/casefiles/diff-unified-bad2.diff") as f:
             diff_text = f.read()
 
-        with assert_raises(exceptions.ApplyException) as ec:
+        with pytest.raises(exceptions.ApplyException) as ec:
             _apply(self.tzu, diff_text)
 
-        e = ec.exception
+        e = ec.value
         e_str = str(e)
         assert "line 1" in e_str
         assert "The Way that can be told of is not the eternal Way;" in e_str
@@ -101,10 +101,10 @@ class ApplyTestSuite(unittest.TestCase):
         with open("tests/casefiles/diff-unified-bad2.diff") as f:
             diff_text = f.read()
 
-        with assert_raises(exceptions.ApplyException) as ec:
+        with pytest.raises(exceptions.ApplyException) as ec:
             _apply("", diff_text)
 
-        e = ec.exception
+        e = ec.value
         e_str = str(e)
         assert "line 1" in e_str
         assert "The Way that can be told of is not the eternal Way;" in e_str
@@ -126,7 +126,7 @@ class ApplyTestSuite(unittest.TestCase):
         new_text = _apply(self.lao, diff_text, use_patch=True)
         self.assertEqual(new_text, (self.tzu, None))
 
-        with assert_raises(exceptions.ApplyException):
+        with pytest.raises(exceptions.ApplyException):
             _apply([""] + self.lao, diff_text, use_patch=True)
 
     def test_diff_rcs(self):
++++++ whatthepatch-0.0.6.tar.gz -> whatthepatch-1.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/.github/workflows/build.yml 
new/whatthepatch-1.0.0/.github/workflows/build.yml
--- old/whatthepatch-0.0.6/.github/workflows/build.yml  1970-01-01 
01:00:00.000000000 +0100
+++ new/whatthepatch-1.0.0/.github/workflows/build.yml  2020-05-31 
21:39:37.000000000 +0200
@@ -0,0 +1,46 @@
+# This workflow will install Python dependencies, run tests and lint with a 
variety of Python versions
+# For more information see: 
https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Build
+
+on:
+  push:
+    branches: [master]
+  pull_request:
+    branches: [master]
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+
+    strategy:
+      matrix:
+        os: [ubuntu-latest, macos-latest, windows-latest]
+        python-version: [3.5, 3.6, 3.7, 3.8]
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up Python ${{ matrix.python-version }} for ${{ matrix.os }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+
+      - name: Display Python version
+        run: python -c "import sys; print(sys.version)"
+
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install flake8 nose
+
+      - name: Lint
+        run: |
+          # stop the build if there are Python syntax errors or undefined names
+          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+          # exit-zero treats all errors as warnings. The GitHub editor is 127 
chars wide
+          flake8 . --count --exit-zero --max-complexity=10 
--max-line-length=127 --statistics
+
+      - name: Test
+        run: |
+          nosetests --with-doctest --doctest-extension=rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/.github/workflows/publish.yml 
new/whatthepatch-1.0.0/.github/workflows/publish.yml
--- old/whatthepatch-0.0.6/.github/workflows/publish.yml        1970-01-01 
01:00:00.000000000 +0100
+++ new/whatthepatch-1.0.0/.github/workflows/publish.yml        2020-05-31 
21:39:37.000000000 +0200
@@ -0,0 +1,30 @@
+# This workflows will upload a Python Package using Twine when a release is 
created
+# For more information see: 
https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
+
+name: Publish package
+
+on:
+  release:
+    types: [created]
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: "3.x"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install setuptools wheel twine
+      - name: Build and publish
+        env:
+          TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
+          TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
+        run: |
+          python setup.py sdist bdist_wheel
+          twine upload dist/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/.travis.yml 
new/whatthepatch-1.0.0/.travis.yml
--- old/whatthepatch-0.0.6/.travis.yml  2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/.travis.yml  1970-01-01 01:00:00.000000000 +0100
@@ -1,30 +0,0 @@
-dist: xenial
-sudo: false
-language: python
-matrix:
-  include:
-    - python: 3.4
-      env: TOX_ENV=py34
-
-    - python: 3.5
-      env: TOX_ENV=py35
-
-    - python: 3.6
-      env: TOX_ENV=py36
-
-    - python: 3.7
-      env: TOX_ENV=py37
-    - python: 3.7
-      env: TOX_ENV=lint
-
-    - python: 2.7
-      env: TOX_ENV=py27
-    - python: 2.7
-      env: TOX_ENV=lint
-addons:
-  apt:
-    packages:
-      - ed
-install: pip install tox
-script: tox -e $TOX_ENV
-cache: pip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/CODE_OF_CONDUCT.md 
new/whatthepatch-1.0.0/CODE_OF_CONDUCT.md
--- old/whatthepatch-0.0.6/CODE_OF_CONDUCT.md   2019-07-20 21:51:06.000000000 
+0200
+++ new/whatthepatch-1.0.0/CODE_OF_CONDUCT.md   2020-05-31 21:39:37.000000000 
+0200
@@ -1,50 +1,130 @@
-# Contributor Code of Conduct
 
-As contributors and maintainers of this project, and in the interest of
-fostering an open and welcoming community, we pledge to respect all people who
-contribute through reporting issues, posting feature requests, updating
-documentation, submitting pull requests or patches, and other activities.
-
-We are committed to making participation in this project a harassment-free
-experience for everyone, regardless of level of experience, gender, gender
-identity and expression, sexual orientation, disability, personal appearance,
-body size, race, ethnicity, age, religion, or nationality.
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery
-* Personal attacks
-* Trolling or insulting/derogatory comments
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
 * Public or private harassment
-* Publishing other's private information, such as physical or electronic
-  addresses, without explicit permission
-* Other unethical or unprofessional conduct
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-By adopting this Code of Conduct, project maintainers commit themselves to
-fairly and consistently applying these principles to every aspect of managing
-this project. Project maintainers who do not follow or enforce the Code of
-Conduct may be permanently removed from the project team.
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for 
moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail 
address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
 
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community.
+## Enforcement
 
 Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting a project maintainer at [[email protected]]. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. Maintainers are
-obligated to maintain confidentiality with regard to the reporter of an
-incident.
+reported to the community leaders responsible for enforcement at
+[INSERT CONTACT METHOD].
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
 
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
 
 This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 1.3.0, available at
-[http://contributor-covenant.org/version/1/3/0/][version]
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
 
-[homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/3/0/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/HISTORY.md 
new/whatthepatch-1.0.0/HISTORY.md
--- old/whatthepatch-0.0.6/HISTORY.md   1970-01-01 01:00:00.000000000 +0100
+++ new/whatthepatch-1.0.0/HISTORY.md   2020-05-31 21:39:37.000000000 +0200
@@ -0,0 +1,55 @@
+# next
+
+- Your PR goes here :)
+
+# 1.0.0
+
+- Issue #26 fix where hardcoded "/tmp" reference was being used
+- Support up to Python 3.8
+- Drop support for Python 2, 3.4
+
+Dev-only:
+
+- Bump Code of Conduct to 2.0
+- Setup Github Actions for package publishing
+- Setup Github Actions for build and testing
+  - Move off Travis and Tox in favor of Github Actions
+
+# 0.0.6
+
+- PR #13 Support for reverse patching (Thanks, @graingert)
+  - This is a breaking change that converted the parsed tuples into
+    namedtuples and added the hunk number to that tuple
+- PR #20 Support up to Python 3.7, drop support for 3.3 (Thanks, @graingert)
+- Issue #18 fix for empty file adds in git
+
+# 0.0.5
+
+- PR #6 Added better support for binary files. (Thanks, @ramusus)
+- PR #3 Added support for git index revision ids that have more than 7 
characters (Thanks, @jopereria)
+
+# 0.0.4
+
+- PR #2 Bug fix for one-liner diffs (Thanks, @thoward)
+- Issue #1 fix where some old real test cases were left failing
+- Added a Code of Conduct
+- Added support for Python 3.5
+
+# 0.0.3
+
+- Better matching for almost all patch headers
+- Support patches that have entire hunks removed
+- Support git patches that are missing index header file modes
+- Moved to MIT license
+- Officially adopt Python 3
+
+# 0.0.2
+
+- Initial support to apply parsed patches
+- Support diffs that do not have headers
+
+# 0.0.1
+
+- The very first release that included parsing support for patches in unified
+  diff format, context diff format, ed diff format, git, bazaar, subversion,
+  and cvs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/LICENSE 
new/whatthepatch-1.0.0/LICENSE
--- old/whatthepatch-0.0.6/LICENSE      2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/LICENSE      2020-05-31 21:39:37.000000000 +0200
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2012 -- 2015 Christopher S. Corley
+Copyright (c) 2012 -- 2020 Christopher S. Corley
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/MANIFEST.in 
new/whatthepatch-1.0.0/MANIFEST.in
--- old/whatthepatch-0.0.6/MANIFEST.in  2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/MANIFEST.in  2020-05-31 21:39:37.000000000 +0200
@@ -1 +1,3 @@
 include README.rst LICENSE
+recursive-include tests *.py
+recursive-include tests/casefiles *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/Makefile 
new/whatthepatch-1.0.0/Makefile
--- old/whatthepatch-0.0.6/Makefile     2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/Makefile     1970-01-01 01:00:00.000000000 +0100
@@ -1,24 +0,0 @@
-all:
-       nosetests
-
-clean:
-       find whatthepatch tests -name '*.pyc' -exec rm {} \;
-
-test:
-       . env2/bin/activate && nosetests || true
-       . env3/bin/activate && nosetests || true
-
-init: init2 init3
-
-init2:
-       virtualenv --python=python2 env2
-       . env2/bin/activate && pip install nose
-       . env2/bin/activate && pip install --editable .
-
-init3:
-       virtualenv --python=python3 env3
-       . env3/bin/activate && pip install nose
-       . env3/bin/activate && pip install --editable .
-
-publish:
-       python setup.py sdist bdist_wheel upload
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/Pipfile 
new/whatthepatch-1.0.0/Pipfile
--- old/whatthepatch-0.0.6/Pipfile      2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/Pipfile      2020-05-31 21:39:37.000000000 +0200
@@ -6,7 +6,6 @@
 [dev-packages]
 nose = "*"
 flake8 = "*"
-tox = "*"
 twine = "*"
 black = "*"
 urllib3 = ">=1.24.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/Pipfile.lock 
new/whatthepatch-1.0.0/Pipfile.lock
--- old/whatthepatch-0.0.6/Pipfile.lock 2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/Pipfile.lock 2020-05-31 21:39:37.000000000 +0200
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": 
"172c4e9a8deaead64717cea107f9072cd599f6e3eedef6d69cc99908a5e347a6"
+            "sha256": 
"05ed891e979eaca6c9cecfdf27832ca00859934b454b3d7b10f01da19b7c6d06"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -19,39 +19,39 @@
     "develop": {
         "appdirs": {
             "hashes": [
-                
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
-                
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
+                
"sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
+                
"sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
             ],
-            "version": "==1.4.3"
+            "version": "==1.4.4"
         },
         "attrs": {
             "hashes": [
-                
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
-                
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
+                
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
+                
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
             ],
-            "version": "==19.1.0"
+            "version": "==19.3.0"
         },
         "black": {
             "hashes": [
-                
"sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf",
-                
"sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"
+                
"sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b",
+                
"sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
             ],
             "index": "pypi",
-            "version": "==19.3b0"
+            "version": "==19.10b0"
         },
         "bleach": {
             "hashes": [
-                
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
-                
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
+                
"sha256:2bce3d8fab545a6528c8fa5d9f9ae8ebc85a56da365c7f85180bfe96a35ef22f",
+                
"sha256:3c4c520fdb9db59ef139915a5db79f8b51bc2a7257ea0389f30c846883430a4b"
             ],
-            "version": "==3.1.0"
+            "version": "==3.1.5"
         },
         "certifi": {
             "hashes": [
-                
"sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939",
-                
"sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"
+                
"sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304",
+                
"sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"
             ],
-            "version": "==2019.6.16"
+            "version": "==2020.4.5.1"
         },
         "chardet": {
             "hashes": [
@@ -62,54 +62,47 @@
         },
         "click": {
             "hashes": [
-                
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
-                
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
+                
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
+                
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
             ],
-            "version": "==7.0"
+            "version": "==7.1.2"
         },
         "docutils": {
             "hashes": [
-                
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
-                
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
-                
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
-            ],
-            "version": "==0.14"
-        },
-        "entrypoints": {
-            "hashes": [
-                
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
-                
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
+                
"sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
+                
"sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
             ],
-            "version": "==0.3"
-        },
-        "filelock": {
-            "hashes": [
-                
"sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59",
-                
"sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"
-            ],
-            "version": "==3.0.12"
+            "version": "==0.16"
         },
         "flake8": {
             "hashes": [
-                
"sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548",
-                
"sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"
+                
"sha256:c69ac1668e434d37a2d2880b3ca9aafd54b3a10a3ac1ab101d22f29e29cf8634",
+                
"sha256:ccaa799ef9893cebe69fdfefed76865aeaefbb94cb8545617b2298786a4de9a5"
             ],
             "index": "pypi",
-            "version": "==3.7.8"
+            "version": "==3.8.2"
         },
         "idna": {
             "hashes": [
-                
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
-                
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
+                
"sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
+                
"sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
             ],
-            "version": "==2.8"
+            "version": "==2.9"
         },
         "importlib-metadata": {
             "hashes": [
-                
"sha256:6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7",
-                
"sha256:cb6ee23b46173539939964df59d3d72c3e0c1b5d54b84f1d8a7e912fe43612db"
+                
"sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f",
+                
"sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"
+            ],
+            "markers": "python_version < '3.8'",
+            "version": "==1.6.0"
+        },
+        "keyring": {
+            "hashes": [
+                
"sha256:3401234209015144a5d75701e71cb47239e552b0882313e9f51e8976f9e27843",
+                
"sha256:c53e0e5ccde3ad34284a40ce7976b5b3a3d6de70344c3f8ee44364cc340976ec"
             ],
-            "version": "==0.18"
+            "version": "==21.2.1"
         },
         "mccabe": {
             "hashes": [
@@ -129,10 +122,17 @@
         },
         "packaging": {
             "hashes": [
-                
"sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
-                
"sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"
+                
"sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8",
+                
"sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"
+            ],
+            "version": "==20.4"
+        },
+        "pathspec": {
+            "hashes": [
+                
"sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0",
+                
"sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"
             ],
-            "version": "==19.0"
+            "version": "==0.8.0"
         },
         "pkginfo": {
             "hashes": [
@@ -141,61 +141,81 @@
             ],
             "version": "==1.5.0.1"
         },
-        "pluggy": {
+        "pycodestyle": {
             "hashes": [
-                
"sha256:0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc",
-                
"sha256:b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c"
+                
"sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367",
+                
"sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"
             ],
-            "version": "==0.12.0"
+            "version": "==2.6.0"
         },
-        "py": {
+        "pyflakes": {
             "hashes": [
-                
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
-                
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
+                
"sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92",
+                
"sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"
             ],
-            "version": "==1.8.0"
+            "version": "==2.2.0"
         },
-        "pycodestyle": {
+        "pygments": {
             "hashes": [
-                
"sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
-                
"sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
+                
"sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
+                
"sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
             ],
-            "version": "==2.5.0"
+            "version": "==2.6.1"
         },
-        "pyflakes": {
+        "pyparsing": {
             "hashes": [
-                
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
-                
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
+                
"sha256:67199f0c41a9c702154efb0e7a8cc08accf830eb003b4d9fa42c4059002e2492",
+                
"sha256:700d17888d441604b0bd51535908dcb297561b040819cccde647a92439db5a2a"
             ],
-            "version": "==2.1.1"
+            "version": "==3.0.0a1"
         },
-        "pygments": {
+        "pywin32-ctypes": {
             "hashes": [
-                
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
-                
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
+                
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
+                
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
             ],
-            "version": "==2.4.2"
+            "markers": "sys_platform == 'win32'",
+            "version": "==0.2.0"
         },
-        "pyparsing": {
+        "readme-renderer": {
             "hashes": [
-                
"sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a",
-                
"sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"
+                
"sha256:cbe9db71defedd2428a1589cdc545f9bd98e59297449f69d721ef8f1cfced68d",
+                
"sha256:cc4957a803106e820d05d14f71033092537a22daa4f406dfbdd61177e0936376"
             ],
-            "version": "==2.4.0"
+            "version": "==26.0"
         },
-        "readme-renderer": {
+        "regex": {
             "hashes": [
-                
"sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f",
-                
"sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d"
+                
"sha256:1386e75c9d1574f6aa2e4eb5355374c8e55f9aac97e224a8a5a6abded0f9c927",
+                
"sha256:27ff7325b297fb6e5ebb70d10437592433601c423f5acf86e5bc1ee2919b9561",
+                
"sha256:329ba35d711e3428db6b45a53b1b13a0a8ba07cbbcf10bbed291a7da45f106c3",
+                
"sha256:3a9394197664e35566242686d84dfd264c07b20f93514e2e09d3c2b3ffdf78fe",
+                
"sha256:51f17abbe973c7673a61863516bdc9c0ef467407a940f39501e786a07406699c",
+                
"sha256:579ea215c81d18da550b62ff97ee187b99f1b135fd894a13451e00986a080cad",
+                
"sha256:70c14743320a68c5dac7fc5a0f685be63bc2024b062fe2aaccc4acc3d01b14a1",
+                
"sha256:7e61be8a2900897803c293247ef87366d5df86bf701083b6c43119c7c6c99108",
+                
"sha256:8044d1c085d49673aadb3d7dc20ef5cb5b030c7a4fa253a593dda2eab3059929",
+                
"sha256:89d76ce33d3266173f5be80bd4efcbd5196cafc34100fdab814f9b228dee0fa4",
+                
"sha256:99568f00f7bf820c620f01721485cad230f3fb28f57d8fbf4a7967ec2e446994",
+                
"sha256:a7c37f048ec3920783abab99f8f4036561a174f1314302ccfa4e9ad31cb00eb4",
+                
"sha256:c2062c7d470751b648f1cacc3f54460aebfc261285f14bc6da49c6943bd48bdd",
+                
"sha256:c9bce6e006fbe771a02bda468ec40ffccbf954803b470a0345ad39c603402577",
+                
"sha256:ce367d21f33e23a84fb83a641b3834dd7dd8e9318ad8ff677fbfae5915a239f7",
+                
"sha256:ce450ffbfec93821ab1fea94779a8440e10cf63819be6e176eb1973a6017aff5",
+                
"sha256:ce5cc53aa9fbbf6712e92c7cf268274eaff30f6bd12a0754e8133d85a8fb0f5f",
+                
"sha256:d466967ac8e45244b9dfe302bbe5e3337f8dc4dec8d7d10f5e950d83b140d33a",
+                
"sha256:d881c2e657c51d89f02ae4c21d9adbef76b8325fe4d5cf0e9ad62f850f3a98fd",
+                
"sha256:e565569fc28e3ba3e475ec344d87ed3cd8ba2d575335359749298a0899fe122e",
+                
"sha256:ea55b80eb0d1c3f1d8d784264a6764f931e172480a2f1868f2536444c5f01e01"
             ],
-            "version": "==24.0"
+            "version": "==2020.5.14"
         },
         "requests": {
             "hashes": [
-                
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
-                
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
+                
"sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
+                
"sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
             ],
-            "version": "==2.22.0"
+            "version": "==2.23.0"
         },
         "requests-toolbelt": {
             "hashes": [
@@ -206,55 +226,66 @@
         },
         "six": {
             "hashes": [
-                
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
-                
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
+                
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
+                
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
             ],
-            "version": "==1.12.0"
+            "version": "==1.15.0"
         },
         "toml": {
             "hashes": [
-                
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
-                
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
-            ],
-            "version": "==0.10.0"
-        },
-        "tox": {
-            "hashes": [
-                
"sha256:dab0b0160dd187b654fc33d690ee1d7bf328bd5b8dc6ef3bb3cc468969c659ba",
-                
"sha256:ee35ffce74933a6c6ac10c9a0182e41763140a5a5070e21b114feca56eaccdcd"
+                
"sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
+                
"sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
             ],
-            "index": "pypi",
-            "version": "==3.13.2"
+            "version": "==0.10.1"
         },
         "tqdm": {
             "hashes": [
-                
"sha256:14a285392c32b6f8222ecfbcd217838f88e11630affe9006cd0e94c7eff3cb61",
-                
"sha256:25d4c0ea02a305a688e7e9c2cdc8f862f989ef2a4701ab28ee963295f5b109ab"
+                
"sha256:4733c4a10d0f2a4d098d801464bdaf5240c7dadd2a7fde4ee93b0a0efd9fb25e",
+                
"sha256:acdafb20f51637ca3954150d0405ff1a7edde0ff19e38fb99a80a66210d2a28f"
             ],
-            "version": "==4.32.2"
+            "version": "==4.46.0"
         },
         "twine": {
             "hashes": [
-                
"sha256:0fb0bfa3df4f62076cab5def36b1a71a2e4acb4d1fa5c97475b048117b1a6446",
-                
"sha256:d6c29c933ecfc74e9b1d9fa13aa1f87c5d5770e119f5a4ce032092f0ff5b14dc"
+                
"sha256:c1af8ca391e43b0a06bbc155f7f67db0bf0d19d284bfc88d1675da497a946124",
+                
"sha256:d561a5e511f70275e5a485a6275ff61851c16ffcb3a95a602189161112d9f160"
             ],
             "index": "pypi",
-            "version": "==1.13.0"
+            "version": "==3.1.1"
         },
-        "urllib3": {
+        "typed-ast": {
             "hashes": [
-                
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
-                
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
+                
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
+                
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
+                
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
+                
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
+                
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
+                
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
+                
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
+                
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
+                
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
+                
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
+                
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
+                
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
+                
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
+                
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
+                
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
+                
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
+                
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
+                
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
+                
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
+                
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
+                
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
             ],
-            "index": "pypi",
-            "version": "==1.25.3"
+            "version": "==1.4.1"
         },
-        "virtualenv": {
+        "urllib3": {
             "hashes": [
-                
"sha256:861bbce3a418110346c70f5c7a696fdcf23a261424e1d28aa4f9362fc2ccbc19",
-                
"sha256:ba8ce6a961d842320681fb90a3d564d0e5134f41dacd0e2bae7f02441dde2d52"
+                
"sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527",
+                
"sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"
             ],
-            "version": "==16.6.2"
+            "index": "pypi",
+            "version": "==1.25.9"
         },
         "webencodings": {
             "hashes": [
@@ -265,18 +296,18 @@
         },
         "wheel": {
             "hashes": [
-                
"sha256:5e79117472686ac0c4aef5bad5172ea73a1c2d1646b808c35926bd26bdfb0c08",
-                
"sha256:62fcfa03d45b5b722539ccbc07b190e4bfff4bb9e3a4d470dd9f6a0981002565"
+                
"sha256:8788e9155fe14f54164c1b9eb0a319d98ef02c160725587ad60f14ddc57b6f96",
+                
"sha256:df277cb51e61359aba502208d680f90c0493adec6f0e848af94948778aed386e"
             ],
             "index": "pypi",
-            "version": "==0.33.4"
+            "version": "==0.34.2"
         },
         "zipp": {
             "hashes": [
-                
"sha256:4970c3758f4e89a7857a973b1e2a5d75bcdc47794442f2e2dd4fe8e0466e809a",
-                
"sha256:8a5712cfd3bb4248015eb3b0b3c54a5f6ee3f2425963ef2a0125b8bc40aafaec"
+                
"sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
+                
"sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
             ],
-            "version": "==0.5.2"
+            "version": "==3.1.0"
         }
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/README.rst 
new/whatthepatch-1.0.0/README.rst
--- old/whatthepatch-0.0.6/README.rst   2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/README.rst   2020-05-31 21:39:37.000000000 +0200
@@ -1,153 +1,165 @@
-What The Patch!?
-================
-
-.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat
-    :target: https://travis-ci.org/cscorley/whatthepatch
-
-What The Patch!? is a library for both parsing and applying patch files.
-
-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
-------------
-
-To install What The Patch!?, simply:
-
-.. code-block:: bash
-
-    $ pip install whatthepatch
-
-Usage
-=====
-
-Let us say we have a patch file containing some changes, aptly named
-'somechanges.patch':
-
-.. code-block:: diff
-
-    --- 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:
-
-.. code-block:: python
-
-    >>> 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:
-
-#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was 
**removed**.
-#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was 
**inserted**.
-#. ``( 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.
-
-.. code-block:: python
-
-    >>> 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!']
-
-
-Contribute
-==========
-
-#. Fork this repository
-#. Create a new branch to work on
-#. Commit your tests and/or changes
-#. Push and create a pull request here!
-
+What The Patch!?
+================
+
+What The Patch!? is a library for both parsing and applying patch files.
+
+Status
+------
+
+.. image:: 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
+^^^^^^^^^^
+
+#. Fork this repository
+#. Create a new branch to work on
+#. Commit your tests and/or changes
+#. 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 <https://pypi.org/project/whatthepatch/>`_
+and can be installed via pip:
+
+.. code-block:: bash
+
+    $ pip install whatthepatch
+
+Usage
+=====
+
+Let us say we have a patch file containing some changes, aptly named
+'somechanges.patch':
+
+.. code-block:: diff
+
+    --- 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:
+
+.. code-block:: python
+
+    >>> 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:
+
+#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was 
**removed**.
+#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was 
**inserted**.
+#. ``( 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.
+
+.. code-block:: python
+
+    >>> 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.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/setup.py 
new/whatthepatch-1.0.0/setup.py
--- old/whatthepatch-0.0.6/setup.py     2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/setup.py     2020-05-31 21:39:37.000000000 +0200
@@ -1,48 +1,40 @@
-# -*- coding: utf-8 -*-
-
-try:
-    from setuptools import setup
-except ImportError:
-    from distutils.core import setup
-
-
-with open('README.rst') as f:
-    readme = f.read()
-
-setup(
-    name='whatthepatch',
-    version='0.0.6',
-    author='Christopher S. Corley',
-    author_email='[email protected]',
-    description='A patch parsing and application library.',
-    long_description=readme,
-    long_description_content_type="text/markdown",
-    url='https://github.com/cscorley/whatthepatch',
-    license='MIT',
-    packages=['whatthepatch'],
-    include_package_data=True,
-    keywords=[
-        "patch",
-        "diff",
-        "parser",
-    ],
-    classifiers=[
-        "Operating System :: OS Independent",
-        "License :: OSI Approved :: MIT License",
-        "Development Status :: 3 - Alpha",
-        "Intended Audience :: Developers",
-        "Intended Audience :: Science/Research",
-        "Topic :: Software Development",
-        "Topic :: Software Development :: Libraries :: Python Modules",
-        "Topic :: Software Development :: Version Control",
-        "Topic :: Text Processing",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.4",
-        "Programming Language :: Python :: 3.5",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
-    ],
-)
+# -*- coding: utf-8 -*-
+
+try:
+    from setuptools import setup
+except ImportError:
+    from distutils.core import setup
+
+
+with open("README.rst") as f:
+    readme = f.read()
+
+setup(
+    name="whatthepatch",
+    version="1.0.0",
+    author="Christopher S. Corley",
+    author_email="[email protected]",
+    description="A patch parsing and application library.",
+    long_description=readme,
+    url="https://github.com/cscorley/whatthepatch";,
+    license="MIT",
+    packages=["whatthepatch"],
+    include_package_data=True,
+    keywords=["patch", "diff", "parser"],
+    classifiers=[
+        "Operating System :: OS Independent",
+        "License :: OSI Approved :: MIT License",
+        "Development Status :: 5 - Production/Stable",
+        "Intended Audience :: Developers",
+        "Intended Audience :: Science/Research",
+        "Topic :: Software Development",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        "Topic :: Software Development :: Version Control",
+        "Topic :: Text Processing",
+        "Programming Language :: Python :: 3 :: Only",
+        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+    ],
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/tests/test_apply.py 
new/whatthepatch-1.0.0/tests/test_apply.py
--- old/whatthepatch-0.0.6/tests/test_apply.py  2019-07-20 21:51:06.000000000 
+0200
+++ new/whatthepatch-1.0.0/tests/test_apply.py  2020-05-31 21:39:37.000000000 
+0200
@@ -2,9 +2,11 @@
 
 import whatthepatch as wtp
 from whatthepatch import exceptions
+from whatthepatch.snippets import which
 
 from nose.tools import assert_raises
 import unittest
+from unittest.case import SkipTest
 
 
 def _apply(src, diff_text, reverse=False, use_patch=False):
@@ -113,6 +115,9 @@
         with open("tests/casefiles/diff-unified.diff") as f:
             diff_text = f.read()
 
+        if not which("patch"):
+            raise SkipTest()
+
         self.assertEqual(_apply(self.lao, diff_text, use_patch=True), 
(self.tzu, None))
         self.assertEqual(
             _apply_r(self.tzu, diff_text, use_patch=True), (self.lao, None)
@@ -139,9 +144,6 @@
         new_text = _apply(self.lao, diff_text)
         self.assertEqual(self.tzu, new_text)
 
-        new_text = _apply(self.lao, diff_text, use_patch=True)
-        self.assertEqual(new_text, (self.tzu, None))
-
 
 if __name__ == "__main__":
     unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/tox.ini 
new/whatthepatch-1.0.0/tox.ini
--- old/whatthepatch-0.0.6/tox.ini      2019-07-20 21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/tox.ini      1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-[tox]
-envlist = py{27,34,35,36,37}, lint
-
-[testenv]
-commands = nosetests --with-doctest --doctest-extension=rst {posargs}
-deps =
-    nose==1.3.7
-
-[testenv:lint]
-deps =
-    flake8==3.7.7
-commands=flake8 whatthepatch tests setup.py
-
-[flake8]
-max-line-length = 88
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/whatthepatch/apply.py 
new/whatthepatch-1.0.0/whatthepatch/apply.py
--- old/whatthepatch-0.0.6/whatthepatch/apply.py        2019-07-20 
21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/whatthepatch/apply.py        2020-05-31 
21:39:37.000000000 +0200
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 
 import subprocess
+import tempfile
+import os.path
 
 from . import patch
 from .exceptions import SubprocessException, HunkApplyException
@@ -32,7 +34,9 @@
     if not patchexec:
         raise SubprocessException("cannot find patch program", code=-1)
 
-    filepath = "/tmp/wtp-" + str(hash(diff.header))
+    tempdir = tempfile.gettempdir()
+
+    filepath = os.path.join(tempdir, "wtp-" + str(hash(diff.header)))
     oldfilepath = filepath + ".old"
     newfilepath = filepath + ".new"
     rejfilepath = filepath + ".rej"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/whatthepatch-0.0.6/whatthepatch/snippets.py 
new/whatthepatch-1.0.0/whatthepatch/snippets.py
--- old/whatthepatch-0.0.6/whatthepatch/snippets.py     2019-07-20 
21:51:06.000000000 +0200
+++ new/whatthepatch-1.0.0/whatthepatch/snippets.py     2020-05-31 
21:39:37.000000000 +0200
@@ -4,30 +4,6 @@
 from shutil import rmtree
 
 
-# order preserving uniq for lists
-def uniq(L):
-    seen = {}
-    result = []
-    for item in L:
-        if item in seen:
-            continue
-        seen[item] = 1
-        result.append(item)
-    return result
-
-
-# exception handling mkdir -p
-def make_dir(dir):
-    try:
-        os.makedirs(dir)
-    except os.error as e:
-        if 17 == e.errno:
-            # the directory already exists
-            pass
-        else:
-            raise e
-
-
 def remove(path):
     if os.path.exists(path):
         if os.path.isdir(path):
@@ -36,19 +12,11 @@
             os.remove(path)
 
 
-# file line length
-def file_len(fname):
-    with open(fname) as f:
-        for i, l in enumerate(f):
-            pass
-    return i + 1
-
-
 # find all indices of a list of strings that match a regex
-def findall_regex(l, r):
+def findall_regex(items, regex):
     found = list()
-    for i in range(0, len(l)):
-        k = r.match(l[i])
+    for i in range(0, len(items)):
+        k = regex.match(items[i])
         if k:
             found.append(i)
             k = None
@@ -56,19 +24,19 @@
     return found
 
 
-def split_by_regex(l, r):
+def split_by_regex(items, regex):
     splits = list()
-    indices = findall_regex(l, r)
+    indices = findall_regex(items, regex)
     k = None
     for i in indices:
         if k is None:
-            splits.append(l[0:i])
+            splits.append(items[0:i])
             k = i
         else:
-            splits.append(l[k:i])
+            splits.append(items[k:i])
             k = i
 
-    splits.append(l[k:])
+    splits.append(items[k:])
 
     return splits
 


Reply via email to