diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..7ecca7d
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,20 @@
+repos:
+  - repo: https://github.com/ambv/black
+    rev: stable
+    hooks:
+      - id: black
+
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v2.0.0
+    hooks:
+      - id: flake8
+
+  - repo: https://github.com/asottile/seed-isort-config
+    rev: v1.7.0
+    hooks:
+      - id: seed-isort-config
+
+  - repo: https://github.com/pre-commit/mirrors-isort
+    rev: v4.3.9
+    hooks:
+      - id: isort
diff --git a/Pipfile b/Pipfile
index 54f6a21..970c04d 100644
--- a/Pipfile
+++ b/Pipfile
@@ -1,20 +1,9 @@
 [packages]
-pip_shims = { path = '.', editable = true, extras = ["tests"] }
+pip_shims = { path = '.', editable = true, extras = ["tests", "dev"] }
 
 [dev-packages]
-invoke = '*'
 sphinx = '*'
 sphinx-rtd-theme = "*"
-parver = '*'
-towncrier = '*'
-wheel = '*'
-black = "*"
-pytest = '*'
-flake8 = '*'
-rope = "*"
-pytest-cov = "*"
-pytest-timeout = "*"
-isort = "*"
 
 [scripts]
 release = 'inv release'
diff --git a/Pipfile.lock b/Pipfile.lock
index e480a86..137607b 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "3981666b91bc417b5c84884392de7e9509c9162345caa0a21051970ea2747676"
+            "sha256": "20a4487b0821cdf8b022499b871dfa2c6de7ab129566a655306cf06656ad1533"
         },
         "pipfile-spec": 6,
         "requires": {},
@@ -21,187 +21,6 @@
             ],
             "version": "==1.5"
         },
-        "atomicwrites": {
-            "hashes": [
-                "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
-                "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
-            ],
-            "version": "==1.2.1"
-        },
-        "attrs": {
-            "hashes": [
-                "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
-                "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
-            ],
-            "version": "==18.2.0"
-        },
-        "colorama": {
-            "hashes": [
-                "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda",
-                "sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1"
-            ],
-            "markers": "sys_platform == 'win32'",
-            "version": "==0.3.9"
-        },
-        "coverage": {
-            "hashes": [
-                "sha256:043d55226aec1d2baf4b2fcab5c204561ccf184a388096f41e396c1c092aff38",
-                "sha256:10bfd0b80b01d0684f968abbe1186bc19962e07b4b7601bb43b175b617cf689d",
-                "sha256:17e59864f19b3233032edb0566f26c25cc7f599503fb34d2645b5ce1fd6c2c3c",
-                "sha256:2105ee183c51fed27e2b6801029b3903f5c2774c78e3f53bd920ca468d0f5679",
-                "sha256:236505d15af6c7b7bfe2a9485db4b2bdea21d9239351483326184314418c79a8",
-                "sha256:237284425271db4f30d458b355decf388ab20b05278bdf8dc9a65de0973726c6",
-                "sha256:26d8eea4c840b73c61a1081d68bceb57b21a2d4f7afda6cac8ac38cb05226b00",
-                "sha256:39a3740f7721155f4269aedf67b211101c07bd2111b334dfd69b807156ab15d9",
-                "sha256:4bd0c42db8efc8a60965769796d43a5570906a870bc819f7388860aa72779d1b",
-                "sha256:4dcddadea47ac30b696956bd18365cd3a86724821656601151e263b86d34798f",
-                "sha256:51ea341289ac4456db946a25bd644f5635e5ae3793df262813cde875887d25c8",
-                "sha256:5415cafb082dad78935b3045c2e5d8907f436d15ad24c3fdb8e1839e084e4961",
-                "sha256:5631f1983074b33c35dbb84607f337b9d7e9808116d7f0f2cb7b9d6d4381d50e",
-                "sha256:5e9249bc361cd22565fd98590a53fd25a3dd666b74791ed7237fa99de938bbed",
-                "sha256:6a48746154f1331f28ef9e889c625b5b15a36cb86dd8021b4bdd1180a2186aa5",
-                "sha256:71d376dbac64855ed693bc1ca121794570fe603e8783cdfa304ec6825d4e768f",
-                "sha256:749ebd8a615337747592bd1523dfc4af7199b2bf6403b55f96c728668aeff91f",
-                "sha256:8ec528b585b95234e9c0c31dcd0a89152d8ed82b4567aa62dbcb3e9a0600deee",
-                "sha256:a1a9ccd879811437ca0307c914f136d6edb85bd0470e6d4966c6397927bcabd9",
-                "sha256:abd956c334752776230b779537d911a5a12fcb69d8fd3fe332ae63a140301ae6",
-                "sha256:ad18f836017f2e8881145795f483636564807aaed54223459915a0d4735300cf",
-                "sha256:b07ac0b1533298ddbc54c9bf3464664895f22899fec027b8d6c8d3ac59023283",
-                "sha256:d9385f1445e30e8e42b75a36a7899ea1fd0f5784233a626625d70f9b087de404",
-                "sha256:db2d1fcd32dbeeb914b2660af1838e9c178b75173f95fd221b1f9410b5d3ef1d",
-                "sha256:e1dec211147f1fd7cb7a0f9a96aeeca467a5af02d38911307b3b8c2324f9917e",
-                "sha256:e96dffc1fa57bb8c1c238f3d989341a97302492d09cb11f77df031112621c35c",
-                "sha256:ed4d97eb0ecdee29d0748acd84e6380729f78ce5ba0c7fe3401801634c25a1c5"
-            ],
-            "version": "==5.0a3"
-        },
-        "execnet": {
-            "hashes": [
-                "sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a",
-                "sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83"
-            ],
-            "version": "==1.5.0"
-        },
-        "funcsigs": {
-            "hashes": [
-                "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
-                "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
-            ],
-            "markers": "python_version < '3.0'",
-            "version": "==1.0.2"
-        },
-        "more-itertools": {
-            "hashes": [
-                "sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
-                "sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
-                "sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
-            ],
-            "version": "==4.3.0"
-        },
-        "pathlib2": {
-            "hashes": [
-                "sha256:8eb170f8d0d61825e09a95b38be068299ddeda82f35e96c3301a8a5e7604cb83",
-                "sha256:d1aa2a11ba7b8f7b21ab852b1fb5afb277e1bb99d5dfc663380b5015c0d80c5a"
-            ],
-            "markers": "python_version < '3.6'",
-            "version": "==2.3.2"
-        },
-        "pip-shims": {
-            "editable": true,
-            "extras": [
-                "tests"
-            ],
-            "path": "."
-        },
-        "pluggy": {
-            "hashes": [
-                "sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
-                "sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
-            ],
-            "version": "==0.8.0"
-        },
-        "py": {
-            "hashes": [
-                "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
-                "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
-            ],
-            "version": "==1.7.0"
-        },
-        "pytest": {
-            "hashes": [
-                "sha256:212be78a6fa5352c392738a49b18f74ae9aeec1040f47c81cadbfd8d1233c310",
-                "sha256:6f6c1efc8d0ccc21f8f6c34d8330baca883cf109b66b3df954b0a117e5528fb4"
-            ],
-            "version": "==3.9.2"
-        },
-        "pytest-cov": {
-            "hashes": [
-                "sha256:513c425e931a0344944f84ea47f3956be0e416d95acbd897a44970c8d926d5d7",
-                "sha256:e360f048b7dae3f2f2a9a4d067b2dd6b6a015d384d1577c994a43f3f7cbad762"
-            ],
-            "version": "==2.6.0"
-        },
-        "pytest-forked": {
-            "hashes": [
-                "sha256:e4500cd0509ec4a26535f7d4112a8cc0f17d3a41c29ffd4eab479d2a55b30805",
-                "sha256:f275cb48a73fc61a6710726348e1da6d68a978f0ec0c54ece5a5fae5977e5a08"
-            ],
-            "version": "==0.2"
-        },
-        "pytest-timeout": {
-            "hashes": [
-                "sha256:1117fc0536e1638862917efbdc0895e6b62fa61e6cf4f39bb655686af7af9627",
-                "sha256:b050a05da96a9992e90e884bc19b4790678b40c25471d2b77015b388417e1fa8"
-            ],
-            "version": "==1.3.2"
-        },
-        "pytest-xdist": {
-            "hashes": [
-                "sha256:06aa39361694c9365baaa03bec71159b59ad06c9826c6279ebba368cb3571561",
-                "sha256:1ef0d05c905cfa0c5442c90e9e350e65c6ada120e33a00a066ca51c89f5f869a"
-            ],
-            "version": "==1.23.2"
-        },
-        "scandir": {
-            "hashes": [
-                "sha256:04b8adb105f2ed313a7c2ef0f1cf7aff4871aa7a1883fa4d8c44b5551ab052d6",
-                "sha256:1444134990356c81d12f30e4b311379acfbbcd03e0bab591de2696a3b126d58e",
-                "sha256:1b5c314e39f596875e5a95dd81af03730b338c277c54a454226978d5ba95dbb6",
-                "sha256:346619f72eb0ddc4cf355ceffd225fa52506c92a2ff05318cfabd02a144e7c4e",
-                "sha256:44975e209c4827fc18a3486f257154d34ec6eaec0f90fef0cca1caa482db7064",
-                "sha256:61859fd7e40b8c71e609c202db5b0c1dbec0d5c7f1449dec2245575bdc866792",
-                "sha256:a5e232a0bf188362fa00123cc0bb842d363a292de7126126df5527b6a369586a",
-                "sha256:c14701409f311e7a9b7ec8e337f0815baf7ac95776cc78b419a1e6d49889a383",
-                "sha256:c7708f29d843fc2764310732e41f0ce27feadde453261859ec0fca7865dfc41b",
-                "sha256:c9009c527929f6e25604aec39b0a43c3f831d2947d89d6caaab22f057b7055c8",
-                "sha256:f5c71e29b4e2af7ccdc03a020c626ede51da471173b4a6ad1e904f2b2e04b4bd"
-            ],
-            "markers": "python_version < '3.5'",
-            "version": "==1.9.0"
-        },
-        "six": {
-            "hashes": [
-                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
-                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
-            ],
-            "version": "==1.11.0"
-        },
-        "wheel": {
-            "hashes": [
-                "sha256:196c9842d79262bb66fcf59faa4bd0deb27da911dbc7c6cdca931080eb1f0783",
-                "sha256:c93e2d711f5f9841e17f53b0e6c0ff85593f3b416b6eec7a9452041a59a42688"
-            ],
-            "version": "==0.32.2"
-        }
-    },
-    "develop": {
-        "alabaster": {
-            "hashes": [
-                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
-                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
-            ],
-            "version": "==0.7.12"
-        },
         "appdirs": {
             "hashes": [
                 "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
@@ -216,41 +35,88 @@
             ],
             "version": "==1.9.0"
         },
+        "aspy.yaml": {
+            "hashes": [
+                "sha256:ae249074803e8b957c83fdd82a99160d0d6d26dff9ba81ba608b42eebd7d8cd3",
+                "sha256:c7390d79f58eb9157406966201abf26da0d56c07e0ff0deadc39c8f4dbc13482"
+            ],
+            "version": "==1.2.0"
+        },
         "atomicwrites": {
             "hashes": [
-                "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
-                "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
+                "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
+                "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
             ],
-            "version": "==1.2.1"
+            "version": "==1.3.0"
         },
         "attrs": {
             "hashes": [
-                "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
-                "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
+                "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
+                "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
             ],
-            "version": "==18.2.0"
+            "version": "==19.1.0"
         },
-        "babel": {
+        "black": {
             "hashes": [
-                "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
-                "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
+                "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf",
+                "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c"
             ],
-            "version": "==2.6.0"
+            "markers": "python_version >= '3.6'",
+            "version": "==19.3b0"
         },
-        "black": {
+        "bleach": {
             "hashes": [
-                "sha256:817243426042db1d36617910df579a54f1afd659adb96fc5032fcf4b36209739",
-                "sha256:e030a9a28f542debc08acceb273f228ac422798e5215ba2a791a6ddeaaca22a5"
+                "sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
+                "sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
             ],
-            "index": "pypi",
-            "version": "==18.9b0"
+            "version": "==3.1.0"
         },
         "certifi": {
             "hashes": [
-                "sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
-                "sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
+                "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
+                "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
+            ],
+            "version": "==2019.3.9"
+        },
+        "cffi": {
+            "hashes": [
+                "sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f",
+                "sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11",
+                "sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d",
+                "sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891",
+                "sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf",
+                "sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c",
+                "sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed",
+                "sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b",
+                "sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a",
+                "sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585",
+                "sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea",
+                "sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f",
+                "sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33",
+                "sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145",
+                "sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a",
+                "sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3",
+                "sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f",
+                "sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd",
+                "sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804",
+                "sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d",
+                "sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92",
+                "sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f",
+                "sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84",
+                "sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb",
+                "sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7",
+                "sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7",
+                "sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35",
+                "sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889"
+            ],
+            "version": "==1.12.2"
+        },
+        "cfgv": {
+            "hashes": [
+                "sha256:39f8475d8eca48639f900daffa3f8bd2f60a31d989df41a9f81c5ad1779a66eb",
+                "sha256:a6a4366d32799a6bfb6f577ebe113b27ba8d1bae43cb57133b1472c1c3dae227"
             ],
-            "version": "==2018.10.15"
+            "version": "==1.5.0"
         },
         "chardet": {
             "hashes": [
@@ -266,6 +132,39 @@
             ],
             "version": "==7.0"
         },
+        "cmarkgfm": {
+            "hashes": [
+                "sha256:0186dccca79483e3405217993b83b914ba4559fe9a8396efc4eea56561b74061",
+                "sha256:1a625afc6f62da428df96ec325dc30866cc5781520cbd904ff4ec44cf018171c",
+                "sha256:207b7673ff4e177374c572feeae0e4ef33be620ec9171c08fd22e2b796e03e3d",
+                "sha256:275905bb371a99285c74931700db3f0c078e7603bed383e8cf1a09f3ee05a3de",
+                "sha256:50098f1c4950722521f0671e54139e0edc1837d63c990cf0f3d2c49607bb51a2",
+                "sha256:50ed116d0b60a07df0dc7b180c28569064b9d37d1578d4c9021cff04d725cb63",
+                "sha256:61a72def110eed903cd1848245897bcb80d295cd9d13944d4f9f30cba5b76655",
+                "sha256:64186fb75d973a06df0e6ea12879533b71f6e7ba1ab01ffee7fc3e7534758889",
+                "sha256:665303d34d7f14f10d7b0651082f25ebf7107f29ef3d699490cac16cdc0fc8ce",
+                "sha256:70b18f843aec58e4e64aadce48a897fe7c50426718b7753aaee399e72df64190",
+                "sha256:761ee7b04d1caee2931344ac6bfebf37102ffb203b136b676b0a71a3f0ea3c87",
+                "sha256:811527e9b7280b136734ed6cb6845e5fbccaeaa132ddf45f0246cbe544016957",
+                "sha256:987b0e157f70c72a84f3c2f9ef2d7ab0f26c08f2bf326c12c087ff9eebcb3ff5",
+                "sha256:9fc6a2183d0a9b0974ec7cdcdad42bd78a3be674cc3e65f87dd694419b3b0ab7",
+                "sha256:a3d17ee4ae739fe16f7501a52255c2e287ac817cfd88565b9859f70520afffea",
+                "sha256:ba5b5488719c0f2ced0aa1986376f7baff1a1653a8eb5fdfcf3f84c7ce46ef8d",
+                "sha256:c573ea89dd95d41b6d8cf36799c34b6d5b1eac4aed0212dee0f0a11fb7b01e8f",
+                "sha256:c5f1b9e8592d2c448c44e6bc0d91224b16ea5f8293908b1561de1f6d2d0658b1",
+                "sha256:cbe581456357d8f0674d6a590b1aaf46c11d01dd0a23af147a51a798c3818034",
+                "sha256:cf219bec69e601fe27e3974b7307d2f06082ab385d42752738ad2eb630a47d65",
+                "sha256:cf5014eb214d814a83a7a47407272d5db10b719dbeaf4d3cfe5969309d0fcf4b",
+                "sha256:d08bad67fa18f7e8ff738c090628ee0cbf0505d74a991c848d6d04abfe67b697",
+                "sha256:d6f716d7b1182bf35862b5065112f933f43dd1aa4f8097c9bcfb246f71528a34",
+                "sha256:e08e479102627641c7cb4ece421c6ed4124820b1758765db32201136762282d9",
+                "sha256:e20ac21418af0298437d29599f7851915497ce9f2866bc8e86b084d8911ee061",
+                "sha256:e25f53c37e319241b9a412382140dffac98ca756ba8f360ac7ab5e30cad9670a",
+                "sha256:e8932bddf159064f04e946fbb64693753488de21586f20e840b3be51745c8c09",
+                "sha256:f20900f16377f2109783ae9348d34bc80530808439591c3d3df73d5c7ef1a00c"
+            ],
+            "version": "==0.4.2"
+        },
         "colorama": {
             "hashes": [
                 "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda",
@@ -283,35 +182,47 @@
         },
         "coverage": {
             "hashes": [
-                "sha256:043d55226aec1d2baf4b2fcab5c204561ccf184a388096f41e396c1c092aff38",
-                "sha256:10bfd0b80b01d0684f968abbe1186bc19962e07b4b7601bb43b175b617cf689d",
-                "sha256:17e59864f19b3233032edb0566f26c25cc7f599503fb34d2645b5ce1fd6c2c3c",
-                "sha256:2105ee183c51fed27e2b6801029b3903f5c2774c78e3f53bd920ca468d0f5679",
-                "sha256:236505d15af6c7b7bfe2a9485db4b2bdea21d9239351483326184314418c79a8",
-                "sha256:237284425271db4f30d458b355decf388ab20b05278bdf8dc9a65de0973726c6",
-                "sha256:26d8eea4c840b73c61a1081d68bceb57b21a2d4f7afda6cac8ac38cb05226b00",
-                "sha256:39a3740f7721155f4269aedf67b211101c07bd2111b334dfd69b807156ab15d9",
-                "sha256:4bd0c42db8efc8a60965769796d43a5570906a870bc819f7388860aa72779d1b",
-                "sha256:4dcddadea47ac30b696956bd18365cd3a86724821656601151e263b86d34798f",
-                "sha256:51ea341289ac4456db946a25bd644f5635e5ae3793df262813cde875887d25c8",
-                "sha256:5415cafb082dad78935b3045c2e5d8907f436d15ad24c3fdb8e1839e084e4961",
-                "sha256:5631f1983074b33c35dbb84607f337b9d7e9808116d7f0f2cb7b9d6d4381d50e",
-                "sha256:5e9249bc361cd22565fd98590a53fd25a3dd666b74791ed7237fa99de938bbed",
-                "sha256:6a48746154f1331f28ef9e889c625b5b15a36cb86dd8021b4bdd1180a2186aa5",
-                "sha256:71d376dbac64855ed693bc1ca121794570fe603e8783cdfa304ec6825d4e768f",
-                "sha256:749ebd8a615337747592bd1523dfc4af7199b2bf6403b55f96c728668aeff91f",
-                "sha256:8ec528b585b95234e9c0c31dcd0a89152d8ed82b4567aa62dbcb3e9a0600deee",
-                "sha256:a1a9ccd879811437ca0307c914f136d6edb85bd0470e6d4966c6397927bcabd9",
-                "sha256:abd956c334752776230b779537d911a5a12fcb69d8fd3fe332ae63a140301ae6",
-                "sha256:ad18f836017f2e8881145795f483636564807aaed54223459915a0d4735300cf",
-                "sha256:b07ac0b1533298ddbc54c9bf3464664895f22899fec027b8d6c8d3ac59023283",
-                "sha256:d9385f1445e30e8e42b75a36a7899ea1fd0f5784233a626625d70f9b087de404",
-                "sha256:db2d1fcd32dbeeb914b2660af1838e9c178b75173f95fd221b1f9410b5d3ef1d",
-                "sha256:e1dec211147f1fd7cb7a0f9a96aeeca467a5af02d38911307b3b8c2324f9917e",
-                "sha256:e96dffc1fa57bb8c1c238f3d989341a97302492d09cb11f77df031112621c35c",
-                "sha256:ed4d97eb0ecdee29d0748acd84e6380729f78ce5ba0c7fe3401801634c25a1c5"
-            ],
-            "version": "==5.0a3"
+                "sha256:029c69deaeeeae1b15bc6c59f0ffa28aa8473721c614a23f2c2976dec245cd12",
+                "sha256:02abbbebc6e9d5abe13cd28b5e963dedb6ffb51c146c916d17b18f141acd9947",
+                "sha256:0384e4479aeb780bfb811eb54c3deb37dbc5e197cd19ec1190cb4b33b254f661",
+                "sha256:1bbfe5b82a3921d285e999c6d256c1e16b31c554c29da62d326f86c173d30337",
+                "sha256:20bbeef0d08e43ef44e10d5863225e178fe100d5778c616260286202bad9d2b4",
+                "sha256:210c02f923df33a8d0e461c86fdcbbb17228ff4f6d92609fc06370a98d283c2d",
+                "sha256:2d0807ba935f540d20b49d5bf1c0237b90ce81e133402feda906e540003f2f7a",
+                "sha256:35d7a013874a7c927ce997350d314144ffc5465faf787bb4e46e6c4f381ef562",
+                "sha256:3636f9d0dcb01aed4180ef2e57a4e34bb4cac3ecd203c2a23db8526d86ab2fb4",
+                "sha256:42f4be770af2455a75e4640f033a82c62f3fb0d7a074123266e143269d7010ef",
+                "sha256:48440b25ba6cda72d4c638f3a9efa827b5b87b489c96ab5f4ff597d976413156",
+                "sha256:494fc6f09b776668cb0d69df5caefb9b90867bd280eb1bd004a63c79fbb09e71",
+                "sha256:4dac8dfd1acf6a3ac657475dfdc66c621f291b1b7422a939cc33c13ac5356473",
+                "sha256:4e8474771c69c2991d5eab65764289a7dd450bbea050bc0ebb42b678d8222b42",
+                "sha256:551f10ddfeff56a1325e5a34eff304c5892aa981fd810babb98bfee77ee2fb17",
+                "sha256:5b104982f1809c1577912519eb249f17d9d7e66304ad026666cb60a5ef73309c",
+                "sha256:5c62aef73dfc87bfcca32cee149a1a7a602bc74bac72223236b0023543511c88",
+                "sha256:633151f8d1ad9467b9f7e90854a7f46ed8f2919e8bc7d98d737833e8938fc081",
+                "sha256:772207b9e2d5bf3f9d283b88915723e4e92d9a62c83f44ec92b9bd0cd685541b",
+                "sha256:7d5e02f647cd727afc2659ec14d4d1cc0508c47e6cfb07aea33d7aa9ca94d288",
+                "sha256:8edc25c1449bdf31acfe183e579bb9c75cec59b55220ccefb6a4f960807ef1d0",
+                "sha256:96d895fba9ed55286368bd4626b8dcbf19b9a529a88e5a6b5c22e0b08c95852a",
+                "sha256:a77589fec63dc7fa6469d8cd122cc285ec034be43d8a2ba600020ddb14277514",
+                "sha256:a9798a4111abb0f94584000ba2a2c74841f2cfe5f9254709756367aabbae0541",
+                "sha256:b33a8f3d6d8946ea1db4ec228606ebc45cf880a7b1d1a26fe8790af677c12b8b",
+                "sha256:b38ea741ab9e35bfa7015c93c93bbd6a1623428f97a67083fc8ebd366238b91f",
+                "sha256:b6a5478c904236543c0347db8a05fac6fc0bd574c870e7970faa88e1d9890044",
+                "sha256:c6248bfc1de36a3844685a2e10ba17c18119ba6252547f921062a323fb31bff1",
+                "sha256:c6c6f84282d3f8953072295ce5cb96cdc56c91f164ef451a5c03be8abb84ad56",
+                "sha256:c705ab445936457359b1424ef25ccc0098b0491b26064677c39f1d14a539f056",
+                "sha256:d95a363d663ceee647291131dbd213af258df24f41350246842481ec3709bd33",
+                "sha256:e27265eb80cdc5dab55a40ef6f890e04ecc618649ad3da5265f128b141f93f78",
+                "sha256:eb62a45b448258bd8b9faa2d12dc2b942259715d7e0d85ebbb3d737be83091d7",
+                "sha256:ebc276c9cb5d917bd2ae959f84ffc279acafa9c9b50b0fa436ebb70bbe2166ea",
+                "sha256:f05a38b77b6c62cff204b0874034d76709769b53a8a7fc5886e02fc4d099d540",
+                "sha256:f4d229866d030863d0fe3bf297d6d11e6133ca15bbb41ed2534a8b9a3d6bd061",
+                "sha256:f95675bd88b51474d4fe5165f3266f419ce754ffadfb97f10323931fa9ac95e5",
+                "sha256:f95bc54fb6d61b9f9ff09c4ae8ff6a3f5edc937cda3ca36fc937302a7c152bf1",
+                "sha256:fd0f6be53de40683584e5331c341e65a679dbe5ec489a0697cec7c2ef1a48cda"
+            ],
+            "version": "==5.0a4"
         },
         "docutils": {
             "hashes": [
@@ -321,23 +232,34 @@
             ],
             "version": "==0.14"
         },
-        "enum34": {
+        "entrypoints": {
             "hashes": [
-                "sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
-                "sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a",
-                "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
-                "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
+                "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
+                "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
             ],
-            "markers": "python_version < '3.4'",
-            "version": "==1.1.6"
+            "version": "==0.3"
+        },
+        "execnet": {
+            "hashes": [
+                "sha256:a7a84d5fa07a089186a329528f127c9d73b9de57f1a1131b82bb5320ee651f6a",
+                "sha256:fc155a6b553c66c838d1a22dba1dc9f5f505c43285a878c6f74a79c024750b83"
+            ],
+            "version": "==1.5.0"
         },
         "flake8": {
             "hashes": [
-                "sha256:6a35f5b8761f45c5513e3405f110a86bea57982c3b75b766ce7b65217abe1670",
-                "sha256:c01f8a3963b3571a8e6bd7a4063359aff90749e160778e03817cd9b71c9e07d2"
+                "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
+                "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"
             ],
-            "index": "pypi",
-            "version": "==3.5.0"
+            "version": "==3.7.7"
+        },
+        "flake8-bugbear": {
+            "hashes": [
+                "sha256:07b6e769d7f4e168d590f7088eae40f6ddd9fa4952bed31602def65842682c83",
+                "sha256:0ccf56975f4db1d69dc1cf3598c99d768ebf95d0cad27d76087954aa399b515a"
+            ],
+            "markers": "python_version >= '3.5'",
+            "version": "==18.8.0"
         },
         "funcsigs": {
             "hashes": [
@@ -347,19 +269,33 @@
             "markers": "python_version < '3.0'",
             "version": "==1.0.2"
         },
+        "identify": {
+            "hashes": [
+                "sha256:407cbb36e8b72b45cfa96a97ae13ccabca4c36557e03616958bd895dfcd3f77d",
+                "sha256:721abbbb1269fa1172799119981c22c5ace022544ce82eedc29b1b0d753baaa5"
+            ],
+            "version": "==1.4.0"
+        },
         "idna": {
             "hashes": [
-                "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
-                "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
+                "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
+                "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
             ],
-            "version": "==2.7"
+            "version": "==2.8"
         },
-        "imagesize": {
+        "importlib": {
             "hashes": [
-                "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
-                "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
+                "sha256:b6ee7066fea66e35f8d0acee24d98006de1a0a8a94a8ce6efe73a9a23c8d9826"
             ],
-            "version": "==1.1.0"
+            "markers": "python_version < '2.7'",
+            "version": "==1.0.4"
+        },
+        "importlib-metadata": {
+            "hashes": [
+                "sha256:a17ce1a8c7bff1e8674cb12c992375d8d0800c9190177ecf0ad93e0097224095",
+                "sha256:b50191ead8c70adfa12495fba19ce6d75f2e0275c14c5a7beb653d6799b512bd"
+            ],
+            "version": "==0.8"
         },
         "incremental": {
             "hashes": [
@@ -374,17 +310,14 @@
                 "sha256:dc492f8f17a0746e92081aec3f86ae0b4750bf41607ea2ad87e5a7b5705121b7",
                 "sha256:eb6f9262d4d25b40330fb21d1e99bf0f85011ccc3526980f8a3eaedd4b43892e"
             ],
-            "index": "pypi",
             "version": "==1.2.0"
         },
         "isort": {
             "hashes": [
-                "sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af",
-                "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8",
-                "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
+                "sha256:18c796c2cd35eb1a1d3f012a214a542790a1aed95e29768bdcb9f2197eccbd0b",
+                "sha256:96151fca2c6e736503981896495d344781b60d18bfda78dc11b290c6125ebdb6"
             ],
-            "index": "pypi",
-            "version": "==4.3.4"
+            "version": "==4.3.15"
         },
         "jinja2": {
             "hashes": [
@@ -395,9 +328,36 @@
         },
         "markupsafe": {
             "hashes": [
-                "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
-            ],
-            "version": "==1.0"
+                "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
+                "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
+                "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
+                "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
+                "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
+                "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
+                "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
+                "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
+                "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
+                "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
+                "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
+                "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
+                "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
+                "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
+                "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
+                "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
+                "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
+                "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
+                "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
+                "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
+                "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
+                "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
+                "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
+                "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
+                "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
+                "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
+                "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
+                "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
+            ],
+            "version": "==1.1.1"
         },
         "mccabe": {
             "hashes": [
@@ -414,20 +374,35 @@
             ],
             "version": "==4.3.0"
         },
-        "packaging": {
+        "mypy": {
+            "hashes": [
+                "sha256:308c274eb8482fbf16006f549137ddc0d69e5a589465e37b99c4564414363ca7",
+                "sha256:e80fd6af34614a0e898a57f14296d0dacb584648f0339c2e000ddbf0f4cc2f8d"
+            ],
+            "markers": "python_version >= '3.5'",
+            "version": "==0.670"
+        },
+        "mypy-extensions": {
             "hashes": [
-                "sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807",
-                "sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9"
+                "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812",
+                "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e"
             ],
-            "version": "==18.0"
+            "markers": "python_version >= '3.5'",
+            "version": "==0.4.1"
+        },
+        "nodeenv": {
+            "hashes": [
+                "sha256:ad8259494cf1c9034539f6cced78a1da4840a4b157e23640bc4a0c0546b0cb7a"
+            ],
+            "markers": "python_version >= '3.5'",
+            "version": "==1.3.3"
         },
         "parver": {
             "hashes": [
-                "sha256:ac4afff688d19d5e1876bb68d4bccc1a1b6a5cc8bd6a646939a14d366695ba15",
-                "sha256:f025fba8f88a9c776971df6d62b6cf7f37d1108f84c163bda91e157d7d527075"
+                "sha256:1b37a691af145a3a193eff269d53ba5b2ab16dfbb65d47d85360755919f5fe4b",
+                "sha256:72d056b8f8883ac90eef5554a9c8a47fac39d3b66479f3d2c8d5bc21b849cdba"
             ],
-            "index": "pypi",
-            "version": "==0.1.1"
+            "version": "==0.2.1"
         },
         "pathlib2": {
             "hashes": [
@@ -437,89 +412,149 @@
             "markers": "python_version < '3.6'",
             "version": "==2.3.2"
         },
+        "pip-shims": {
+            "editable": true,
+            "extras": [
+                "tests"
+            ],
+            "path": ".",
+            "version": "==0.3.3.dev0"
+        },
+        "pkginfo": {
+            "hashes": [
+                "sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb",
+                "sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32"
+            ],
+            "version": "==1.5.0.1"
+        },
         "pluggy": {
             "hashes": [
-                "sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
-                "sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
+                "sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f",
+                "sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746"
+            ],
+            "version": "==0.9.0"
+        },
+        "pre-commit": {
+            "hashes": [
+                "sha256:d3d69c63ae7b7584c4b51446b0b583d454548f9df92575b2fe93a68ec800c4d3",
+                "sha256:fc512f129b9526e35e80d656a16a31c198f584c4fce3a5c739045b5140584917"
             ],
-            "version": "==0.8.0"
+            "version": "==1.14.4"
         },
         "py": {
             "hashes": [
-                "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
-                "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
+                "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
+                "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
             ],
-            "version": "==1.7.0"
+            "version": "==1.8.0"
         },
         "pycodestyle": {
             "hashes": [
-                "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
-                "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
+                "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
+                "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
             ],
-            "version": "==2.4.0"
+            "version": "==2.5.0"
         },
-        "pyflakes": {
+        "pycparser": {
             "hashes": [
-                "sha256:9a7662ec724d0120012f6e29d6248ae3727d821bba522a0e6b356eff19126a49",
-                "sha256:f661252913bc1dbe7fcfcbf0af0db3f42ab65aabd1a6ca68fe5d466bace94dae"
+                "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
             ],
-            "version": "==2.0.0"
+            "version": "==2.19"
         },
-        "pygments": {
+        "pyflakes": {
             "hashes": [
-                "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
-                "sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
+                "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
+                "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
             ],
-            "version": "==2.2.0"
+            "version": "==2.1.1"
         },
-        "pyparsing": {
+        "pygments": {
             "hashes": [
-                "sha256:bc6c7146b91af3f567cf6daeaec360bc07d45ffec4cf5353f4d7a208ce7ca30a",
-                "sha256:d29593d8ebe7b57d6967b62494f8c72b03ac0262b1eed63826c6f788b3606401"
+                "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
+                "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
             ],
-            "version": "==2.2.2"
+            "version": "==2.3.1"
         },
         "pytest": {
             "hashes": [
-                "sha256:212be78a6fa5352c392738a49b18f74ae9aeec1040f47c81cadbfd8d1233c310",
-                "sha256:6f6c1efc8d0ccc21f8f6c34d8330baca883cf109b66b3df954b0a117e5528fb4"
+                "sha256:592eaa2c33fae68c7d75aacf042efc9f77b27c08a6224a4f59beab8d9a420523",
+                "sha256:ad3ad5c450284819ecde191a654c09b0ec72257a2c711b9633d677c71c9850c4"
             ],
-            "version": "==3.9.2"
+            "version": "==4.3.1"
         },
         "pytest-cov": {
             "hashes": [
-                "sha256:513c425e931a0344944f84ea47f3956be0e416d95acbd897a44970c8d926d5d7",
-                "sha256:e360f048b7dae3f2f2a9a4d067b2dd6b6a015d384d1577c994a43f3f7cbad762"
+                "sha256:0ab664b25c6aa9716cbf203b17ddb301932383046082c081b9848a0edf5add33",
+                "sha256:230ef817450ab0699c6cc3c9c8f7a829c34674456f2ed8df1fe1d39780f7c87f"
             ],
-            "version": "==2.6.0"
+            "version": "==2.6.1"
+        },
+        "pytest-forked": {
+            "hashes": [
+                "sha256:5fe33fbd07d7b1302c95310803a5e5726a4ff7f19d5a542b7ce57c76fed8135f",
+                "sha256:d352aaced2ebd54d42a65825722cb433004b4446ab5d2044851d9cc7a00c9e38"
+            ],
+            "version": "==1.0.2"
         },
         "pytest-timeout": {
             "hashes": [
-                "sha256:1117fc0536e1638862917efbdc0895e6b62fa61e6cf4f39bb655686af7af9627",
-                "sha256:b050a05da96a9992e90e884bc19b4790678b40c25471d2b77015b388417e1fa8"
+                "sha256:4a30ba76837a32c7b7cd5c84ee9933fde4b9022b0cd20ea7d4a577c2a1649fb1",
+                "sha256:d49f618c6448c14168773b6cdda022764c63ea80d42274e3156787e8088d04c6"
             ],
-            "version": "==1.3.2"
+            "version": "==1.3.3"
         },
-        "pytz": {
+        "pytest-xdist": {
+            "hashes": [
+                "sha256:4a201bb3ee60f5dd6bb40c5209d4e491cecc4d5bafd656cfb10f86178786e568",
+                "sha256:d03d1ff1b008458ed04fa73e642d840ac69b4107c168e06b71037c62d7813dd4"
+            ],
+            "version": "==1.26.1"
+        },
+        "pyyaml": {
+            "hashes": [
+                "sha256:1adecc22f88d38052fb787d959f003811ca858b799590a5eaa70e63dca50308c",
+                "sha256:436bc774ecf7c103814098159fbb84c2715d25980175292c648f2da143909f95",
+                "sha256:460a5a4248763f6f37ea225d19d5c205677d8d525f6a83357ca622ed541830c2",
+                "sha256:5a22a9c84653debfbf198d02fe592c176ea548cccce47553f35f466e15cf2fd4",
+                "sha256:7a5d3f26b89d688db27822343dfa25c599627bc92093e788956372285c6298ad",
+                "sha256:9372b04a02080752d9e6f990179a4ab840227c6e2ce15b95e1278456664cf2ba",
+                "sha256:a5dcbebee834eaddf3fa7366316b880ff4062e4bcc9787b78c7fbb4a26ff2dd1",
+                "sha256:aee5bab92a176e7cd034e57f46e9df9a9862a71f8f37cad167c6fc74c65f5b4e",
+                "sha256:c51f642898c0bacd335fc119da60baae0824f2cde95b0330b56c0553439f0673",
+                "sha256:c68ea4d3ba1705da1e0d85da6684ac657912679a649e8868bd850d2c299cce13",
+                "sha256:e23d0cc5299223dcc37885dae624f382297717e459ea24053709675a976a3e19"
+            ],
+            "version": "==5.1"
+        },
+        "readme-renderer": {
+            "extras": [
+                "md"
+            ],
             "hashes": [
-                "sha256:642253af8eae734d1509fc6ac9c1aee5e5b69d76392660889979b9870610a46b",
-                "sha256:91e3ccf2c344ffaa6defba1ce7f38f97026943f675b7703f44789768e4cb0ece"
+                "sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f",
+                "sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d"
             ],
-            "version": "==2018.6"
+            "version": "==24.0"
         },
         "requests": {
             "hashes": [
-                "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c",
-                "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279"
+                "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
+                "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
+            ],
+            "version": "==2.21.0"
+        },
+        "requests-toolbelt": {
+            "hashes": [
+                "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f",
+                "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"
             ],
-            "version": "==2.20.0"
+            "version": "==0.9.1"
         },
         "rope": {
             "hashes": [
-                "sha256:a108c445e1cd897fe19272ab7877d172e7faf3d4148c80e7d20faba42ea8f7b2"
+                "sha256:031eb54b3eeec89f4304ede816995ed2b93a21e6fba16bd02aff10a0d6c257b7"
             ],
-            "index": "pypi",
-            "version": "==0.11.0"
+            "version": "==0.12.0"
         },
         "scandir": {
             "hashes": [
@@ -540,10 +575,242 @@
         },
         "six": {
             "hashes": [
-                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
-                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
+                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
+                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
+            ],
+            "version": "==1.12.0"
+        },
+        "toml": {
+            "hashes": [
+                "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
+                "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e",
+                "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"
+            ],
+            "version": "==0.10.0"
+        },
+        "towncrier": {
+            "hashes": [
+                "sha256:48251a1ae66d2cf7e6fa5552016386831b3e12bb3b2d08eb70374508c17a8196",
+                "sha256:de19da8b8cb44f18ea7ed3a3823087d2af8fcf497151bb9fd1e1b092ff56ed8d"
+            ],
+            "version": "==19.2.0"
+        },
+        "tqdm": {
+            "hashes": [
+                "sha256:d385c95361699e5cf7622485d9b9eae2d4864b21cd5a2374a9c381ffed701021",
+                "sha256:e22977e3ebe961f72362f6ddfb9197cc531c9737aaf5f607ef09740c849ecd05"
+            ],
+            "version": "==4.31.1"
+        },
+        "twine": {
+            "hashes": [
+                "sha256:0fb0bfa3df4f62076cab5def36b1a71a2e4acb4d1fa5c97475b048117b1a6446",
+                "sha256:d6c29c933ecfc74e9b1d9fa13aa1f87c5d5770e119f5a4ce032092f0ff5b14dc"
+            ],
+            "version": "==1.13.0"
+        },
+        "typed-ast": {
+            "hashes": [
+                "sha256:035a54ede6ce1380599b2ce57844c6554666522e376bd111eb940fbc7c3dad23",
+                "sha256:037c35f2741ce3a9ac0d55abfcd119133cbd821fffa4461397718287092d9d15",
+                "sha256:049feae7e9f180b64efacbdc36b3af64a00393a47be22fa9cb6794e68d4e73d3",
+                "sha256:19228f7940beafc1ba21a6e8e070e0b0bfd1457902a3a81709762b8b9039b88d",
+                "sha256:2ea681e91e3550a30c2265d2916f40a5f5d89b59469a20f3bad7d07adee0f7a6",
+                "sha256:3a6b0a78af298d82323660df5497bcea0f0a4a25a0b003afd0ce5af049bd1f60",
+                "sha256:5385da8f3b801014504df0852bf83524599df890387a3c2b17b7caa3d78b1773",
+                "sha256:606d8afa07eef77280c2bf84335e24390055b478392e1975f96286d99d0cb424",
+                "sha256:69245b5b23bbf7fb242c9f8f08493e9ecd7711f063259aefffaeb90595d62287",
+                "sha256:6f6d839ab09830d59b7fa8fb6917023d8cb5498ee1f1dbd82d37db78eb76bc99",
+                "sha256:730888475f5ac0e37c1de4bd05eeb799fdb742697867f524dc8a4cd74bcecc23",
+                "sha256:9819b5162ffc121b9e334923c685b0d0826154e41dfe70b2ede2ce29034c71d8",
+                "sha256:9e60ef9426efab601dd9aa120e4ff560f4461cf8442e9c0a2b92548d52800699",
+                "sha256:af5fbdde0690c7da68e841d7fc2632345d570768ea7406a9434446d7b33b0ee1",
+                "sha256:b64efdbdf3bbb1377562c179f167f3bf301251411eb5ac77dec6b7d32bcda463",
+                "sha256:bac5f444c118aeb456fac1b0b5d14c6a71ea2a42069b09c176f75e9bd4c186f6",
+                "sha256:bda9068aafb73859491e13b99b682bd299c1b5fd50644d697533775828a28ee0",
+                "sha256:d659517ca116e6750101a1326107d3479028c5191f0ecee3c7203c50f5b915b0",
+                "sha256:eddd3fb1f3e0f82e5915a899285a39ee34ce18fd25d89582bc89fc9fb16cd2c6"
+            ],
+            "version": "==1.3.1"
+        },
+        "urllib3": {
+            "hashes": [
+                "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
+                "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
+            ],
+            "version": "==1.24.1"
+        },
+        "virtualenv": {
+            "hashes": [
+                "sha256:6aebaf4dd2568a0094225ebbca987859e369e3e5c22dc7d52e5406d504890417",
+                "sha256:984d7e607b0a5d1329425dd8845bd971b957424b5ba664729fab51ab8c11bc39"
+            ],
+            "version": "==16.4.3"
+        },
+        "webencodings": {
+            "hashes": [
+                "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
+                "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
+            ],
+            "version": "==0.5.1"
+        },
+        "wheel": {
+            "hashes": [
+                "sha256:66a8fd76f28977bb664b098372daef2b27f60dc4d1688cfab7b37a09448f0e9d",
+                "sha256:8eb4a788b3aec8abf5ff68d4165441bc57420c9f64ca5f471f58c3969fe08668"
+            ],
+            "version": "==0.33.1"
+        },
+        "zipp": {
+            "hashes": [
+                "sha256:55ca87266c38af6658b84db8cfb7343cdb0bf275f93c7afaea0d8e7a209c7478",
+                "sha256:682b3e1c62b7026afe24eadf6be579fb45fec54c07ea218bded8092af07a68c4"
+            ],
+            "version": "==0.3.3"
+        }
+    },
+    "develop": {
+        "alabaster": {
+            "hashes": [
+                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
+                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
+            ],
+            "version": "==0.7.12"
+        },
+        "babel": {
+            "hashes": [
+                "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
+                "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
+            ],
+            "version": "==2.6.0"
+        },
+        "certifi": {
+            "hashes": [
+                "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
+                "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
+            ],
+            "version": "==2019.3.9"
+        },
+        "chardet": {
+            "hashes": [
+                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
+                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
+            ],
+            "version": "==3.0.4"
+        },
+        "docutils": {
+            "hashes": [
+                "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
+                "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
+                "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
+            ],
+            "version": "==0.14"
+        },
+        "enum34": {
+            "hashes": [
+                "sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
+                "sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a",
+                "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
+                "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
+            ],
+            "markers": "python_version < '3.4'",
+            "version": "==1.1.6"
+        },
+        "idna": {
+            "hashes": [
+                "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
+                "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
+            ],
+            "version": "==2.8"
+        },
+        "imagesize": {
+            "hashes": [
+                "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
+                "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
+            ],
+            "version": "==1.1.0"
+        },
+        "jinja2": {
+            "hashes": [
+                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
+                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
+            ],
+            "version": "==2.10"
+        },
+        "markupsafe": {
+            "hashes": [
+                "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
+                "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
+                "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
+                "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
+                "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
+                "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
+                "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
+                "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
+                "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
+                "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
+                "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
+                "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
+                "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
+                "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
+                "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
+                "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
+                "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
+                "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
+                "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
+                "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
+                "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
+                "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
+                "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
+                "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
+                "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
+                "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
+                "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
+                "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
+            ],
+            "version": "==1.1.1"
+        },
+        "packaging": {
+            "hashes": [
+                "sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
+                "sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"
+            ],
+            "version": "==19.0"
+        },
+        "pygments": {
+            "hashes": [
+                "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
+                "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
+            ],
+            "version": "==2.3.1"
+        },
+        "pyparsing": {
+            "hashes": [
+                "sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a",
+                "sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3"
+            ],
+            "version": "==2.3.1"
+        },
+        "pytz": {
+            "hashes": [
+                "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
+                "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
+            ],
+            "version": "==2018.9"
+        },
+        "requests": {
+            "hashes": [
+                "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
+                "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
+            ],
+            "version": "==2.21.0"
+        },
+        "six": {
+            "hashes": [
+                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
+                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
             ],
-            "version": "==1.11.0"
+            "version": "==1.12.0"
         },
         "snowballstemmer": {
             "hashes": [
@@ -562,56 +829,74 @@
         },
         "sphinx-rtd-theme": {
             "hashes": [
-                "sha256:02f02a676d6baabb758a20c7a479d58648e0f64f13e07d1b388e9bb2afe86a09",
-                "sha256:d0f6bc70f98961145c5b0e26a992829363a197321ba571b31b24ea91879e0c96"
+                "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4",
+                "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"
             ],
             "index": "pypi",
-            "version": "==0.4.2"
+            "version": "==0.4.3"
         },
-        "sphinxcontrib-websupport": {
+        "sphinxcontrib-applehelp": {
             "hashes": [
-                "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
-                "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
+                "sha256:edaa0ab2b2bc74403149cb0209d6775c96de797dfd5b5e2a71981309efab3897",
+                "sha256:fb8dee85af95e5c30c91f10e7eb3c8967308518e0f7488a2828ef7bc191d0d5d"
             ],
-            "version": "==1.1.0"
+            "markers": "python_version >= '3.5'",
+            "version": "==1.0.1"
         },
-        "toml": {
+        "sphinxcontrib-devhelp": {
             "hashes": [
-                "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
-                "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
+                "sha256:6c64b077937330a9128a4da74586e8c2130262f014689b4b89e2d08ee7294a34",
+                "sha256:9512ecb00a2b0821a146736b39f7aeb90759834b07e81e8cc23a9c70bacb9981"
             ],
-            "version": "==0.10.0"
+            "markers": "python_version >= '3.5'",
+            "version": "==1.0.1"
         },
-        "towncrier": {
+        "sphinxcontrib-htmlhelp": {
             "hashes": [
-                "sha256:3c0da1de042861df9030c0608d346d55cabe14cfa7cf04045f22b0af63eb8aa7",
-                "sha256:cfde66ada782db9269407eaefb38562d3d2a4bc4d7647c0b2197ed184b869aae"
+                "sha256:0d691ca8edf5995fbacfe69b191914256071a94cbad03c3688dca47385c9206c",
+                "sha256:e31c8271f5a8f04b620a500c0442a7d5cfc1a732fa5c10ec363f90fe72af0cb8"
             ],
-            "index": "pypi",
-            "version": "==18.6.0"
+            "markers": "python_version >= '3.5'",
+            "version": "==1.0.1"
         },
-        "typing": {
+        "sphinxcontrib-jsmath": {
             "hashes": [
-                "sha256:3a887b021a77b292e151afb75323dea88a7bc1b3dfa92176cff8e44c8b68bddf",
-                "sha256:b2c689d54e1144bbcfd191b0832980a21c2dbcf7b5ff7a66248a60c90e951eb8",
-                "sha256:d400a9344254803a2368533e4533a4200d21eb7b6b729c173bc38201a74db3f2"
+                "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178",
+                "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"
             ],
-            "markers": "python_version < '3.5'",
-            "version": "==3.6.4"
+            "markers": "python_version >= '3.5'",
+            "version": "==1.0.1"
         },
-        "urllib3": {
+        "sphinxcontrib-qthelp": {
             "hashes": [
-                "sha256:41c3db2fc01e5b907288010dec72f9d0a74e37d6994e6eb56849f59fea2265ae",
-                "sha256:8819bba37a02d143296a4d032373c4dd4aca11f6d4c9973335ca75f9c8475f59"
+                "sha256:513049b93031beb1f57d4daea74068a4feb77aa5630f856fcff2e50de14e9a20",
+                "sha256:79465ce11ae5694ff165becda529a600c754f4bc459778778c7017374d4d406f"
             ],
-            "version": "==1.24"
+            "markers": "python_version >= '3.5'",
+            "version": "==1.0.2"
         },
-        "wheel": {
+        "sphinxcontrib-serializinghtml": {
+            "hashes": [
+                "sha256:01d9b2617d7e8ddf7a00cae091f08f9fa4db587cc160b493141ee56710810932",
+                "sha256:392187ac558863b8aff0d76dc78e0731fed58f3b06e2b00e22995dcdb630f213"
+            ],
+            "markers": "python_version >= '3.5'",
+            "version": "==1.1.1"
+        },
+        "sphinxcontrib-websupport": {
+            "hashes": [
+                "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
+                "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
+            ],
+            "markers": "python_version < '3.5'",
+            "version": "==1.1.0"
+        },
+        "urllib3": {
             "hashes": [
-                "sha256:196c9842d79262bb66fcf59faa4bd0deb27da911dbc7c6cdca931080eb1f0783",
-                "sha256:c93e2d711f5f9841e17f53b0e6c0ff85593f3b416b6eec7a9452041a59a42688"
+                "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
+                "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
             ],
-            "version": "==0.32.2"
+            "version": "==1.24.1"
         }
     }
 }
diff --git a/README.rst b/README.rst
index bf5d542..c9ef896 100644
--- a/README.rst
+++ b/README.rst
@@ -61,13 +61,11 @@ Summary
 
 **pip-shims** is a set of compatibilty access shims to the `pip`_ internal API. **pip-shims**
 provides compatibility with pip versions 8.0 through the current release (18.x).  The shims
-are provided using a lazy import strategy (powered by `modutil`_ where possible, falling
-back to *importlib* from the standard library with a lazy import strategy otherwise).
+are provided using a lazy import strategy by hacking a module by overloading a class instance's *getattr* method.
 This library exists due to my constant writing of the same set of import shims across
 many different libraries, including `pipenv`_, `pip-tools`_, `requirementslib`_, and
 `passa`_.
 
-.. _modutil: https://github.com/sarugaku/pipfile
 .. _passa: https://github.com/sarugaku/passa
 .. _pip: https://github.com/pypa/pip
 .. _pipenv: https://github.com/pypa/pipenv
@@ -103,10 +101,12 @@ req.constructors   _strip_extras               req.req_install
 cli                cmdoptions                  cmdoptions
 cli.base_command   Command                     basecommand
 cli.parser         ConfigOptionParser          baseparser
+commands.freeze    DEV_PKGS
 exceptions         DistributionNotFound
 utils.hashes       FAVORITE_HASH
 models             FormatControl               index
 utils.misc         get_installed_distributions utils
+utils.compat       stdlib_pkgs                 compat
 cli.cmdoptions     index_group                 cmdoptions
 req.req_install    InstallRequirement
 req.constructors   install_req_from_line       req.req_install.InstallRequirement
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index e21b15c..5e2fcca 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -61,13 +61,11 @@ Summary
 
 **pip-shims** is a set of compatibilty access shims to the `pip`_ internal API. **pip-shims**
 provides compatibility with pip versions 8.0 through the current release (18.x).  The shims
-are provided using a lazy import strategy (powered by `modutil`_ where possible, falling
-back to *importlib* from the standard library with a lazy import strategy otherwise).
+are provided using a lazy import strategy by hacking a module by overloading a class instance's *getattr* method.
 This library exists due to my constant writing of the same set of import shims across
 many different libraries, including `pipenv`_, `pip-tools`_, `requirementslib`_, and
 `passa`_.
 
-.. _modutil: https://github.com/sarugaku/pipfile
 .. _passa: https://github.com/sarugaku/passa
 .. _pip: https://github.com/pypa/pip
 .. _pipenv: https://github.com/pypa/pipenv
@@ -106,10 +104,12 @@ req.constructors   _strip_extras               req.req_install
 cli                cmdoptions                  cmdoptions
 cli.base_command   Command                     basecommand
 cli.parser         ConfigOptionParser          baseparser
+commands.freeze    DEV_PKGS
 exceptions         DistributionNotFound
 utils.hashes       FAVORITE_HASH
 models             FormatControl               index
 utils.misc         get_installed_distributions utils
+utils.compat       stdlib_pkgs                 compat
 cli.cmdoptions     index_group                 cmdoptions
 req.req_install    InstallRequirement
 req.constructors   install_req_from_line       req.req_install.InstallRequirement
diff --git a/news/25.feature.rst b/news/25.feature.rst
new file mode 100644
index 0000000..c8c9e58
--- /dev/null
+++ b/news/25.feature.rst
@@ -0,0 +1,1 @@
+Added ``commands.freeze.DEV_PKGS`` and ``utils.compat.stdlib_pkgs`` shims.
diff --git a/pyproject.toml b/pyproject.toml
index a0372f3..9cf5365 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,24 @@
 [build-system]
-requires = ['setuptools>=36.2.2', 'wheel>=0.28.0']
+requires = ['setuptools>=40.8.0', 'wheel>=0.33.0']
+
+[tool.black]
+line-length = 90
+include = '\.pyi?$'
+exclude = '''
+/(
+    \.eggs
+  | \.git
+  | \.hg
+  | \.mypy_cache
+  | \.tox
+  | \.pyre_configuration
+  | \.venv
+  | _build
+  | buck-out
+  | build
+  | dist
+)
+'''
 
 [tool.towncrier]
 package = 'pip_shims'
diff --git a/setup.cfg b/setup.cfg
index 063ba98..f789c18 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,13 +33,15 @@ classifier =
 [options]
 zip_safe = true
 python_requires = >=2.6,!=3.0,!=3.1,!=3.2,!=3.3
-setup_requires = setuptools>=36.2.2
+setup_requires =
+    setuptools>=40.8.0
+    wheel
 install_requires =
     pip
     wheel
     setuptools
     six
-    importlib; python_version<"2.7"
+    importlib;python_version<"2.7"
 
 [options.extras_require]
 tests =
@@ -47,33 +49,58 @@ tests =
     pytest>=3.6.0
     pytest-xdist
     pytest-cov
+    twine
+    readme-renderer[md]
+dev =
+    pre-commit
+    mypy;python_version>="3.5"
+    isort
+    flake8
+    flake8-bugbear;python_version>="3.5"
+    rope
+    black;python_version>="3.6"
+    invoke
+    parver
+    towncrier
+    wheel
 
 [bdist_wheel]
 universal = 1
 
 [tool:pytest]
 strict = true
+plugins = cov flake8
 addopts = -ra
 testpaths = tests/
 norecursedirs = .* build dist news tasks docs
+flake8-ignore =
+    docs/source/* ALL
+    tests/*.py ALL
+    setup.py ALL
+filterwarnings =
+    ignore::DeprecationWarning
+    ignore::PendingDeprecationWarning
 
 [isort]
-atomic=true
-lines_after_imports=2
-lines_between_types=1
-multi_line_output=5
-not_skip=__init__.py
-known_first_party =
-    pip_shims
-    tests
-ignore_trailing_comma=true
+atomic = true
+not_skip = __init__.py
+line_length = 90
+indent = '    '
+multi_line_output = 3
+known_third_party =invoke,parver,pytest,setuptools,six,towncrier
+known_first_party = pip_shims,tests
+combine_as_imports=True
+include_trailing_comma = True
+force_grid_wrap=0
 
 [flake8]
-exclude = .git,__pycache__,docs/,*.egg,build,data
-select = E,W,F
+max-line-length = 90
+select = C,E,F,W,B,B950
+# select = E,W,F
 ignore =
     # The default ignore list:
-    E121,E123,E126,E226,E24,E704,
+    # E121,E123,E126,E226,E24,E704,
+    D203,F401,E123,E203,W503,E501
     # Our additions:
     # E127: continuation line over-indented for visual indent
     # E128: continuation line under-indented for visual indent
@@ -82,4 +109,18 @@ ignore =
     # E231: missing whitespace after ','
     # E402: module level import not at top of file
     # E501: line too long
-    E127,E128,E129,E222,E231,E402,E501
+    # E231,E402,E501
+exclude =
+    .tox,
+    .git,
+    __pycache__,
+    docs/source/*,
+    build,
+    dist,
+    tests/*,
+    *.pyc,
+    *.egg-info,
+    .cache,
+    .eggs,
+    setup.py,
+max-complexity=13
diff --git a/src/pip_shims/shims.py b/src/pip_shims/shims.py
index 34de690..5ea2691 100644
--- a/src/pip_shims/shims.py
+++ b/src/pip_shims/shims.py
@@ -1,26 +1,38 @@
 # -*- coding=utf-8 -*-
-from collections import namedtuple
-from contextlib import contextmanager
 import importlib
 import os
 import sys
-
+from collections import namedtuple
+from contextlib import contextmanager
 
 import six
-six.add_move(six.MovedAttribute("Callable", "collections", "collections.abc"))
-from six.moves import Callable
+
+# format: off
+six.add_move(six.MovedAttribute("Callable", "collections", "collections.abc"))  # noqa
+from six.moves import Callable  # type: ignore  # noqa  # isort:skip
+
+# format: on
 
 
 class _shims(object):
-    CURRENT_PIP_VERSION  = "18.1"
+    CURRENT_PIP_VERSION = "19.0.3"
     BASE_IMPORT_PATH = os.environ.get("PIP_SHIMS_BASE_MODULE", "pip")
     path_info = namedtuple("PathInfo", "path start_version end_version")
 
     def __dir__(self):
         result = list(self._locations.keys()) + list(self.__dict__.keys())
-        result.extend(('__file__', '__doc__', '__all__',
-                       '__docformat__', '__name__', '__path__',
-                       '__package__', '__version__'))
+        result.extend(
+            (
+                "__file__",
+                "__doc__",
+                "__all__",
+                "__docformat__",
+                "__name__",
+                "__path__",
+                "__package__",
+                "__version__",
+            )
+        )
         return result
 
     @classmethod
@@ -34,13 +46,14 @@ class _shims(object):
     def __init__(self):
         # from .utils import _parse, get_package, STRING_TYPES
         from . import utils
+
         self.utils = utils
         self._parse = utils._parse
         self.get_package = utils.get_package
         self.STRING_TYPES = utils.STRING_TYPES
         self._modules = {
             "pip": importlib.import_module(self.BASE_IMPORT_PATH),
-            "pip_shims.utils": utils
+            "pip_shims.utils": utils,
         }
         self.pip_version = getattr(self._modules["pip"], "__version__")
         version_types = ["post", "pre", "dev", "rc"]
@@ -62,15 +75,15 @@ class _shims(object):
             ),
             "cmdoptions": (
                 ("cli.cmdoptions", "18.1", "9999"),
-                ("cmdoptions", "7.0.0", "18.0")
+                ("cmdoptions", "7.0.0", "18.0"),
             ),
             "Command": (
                 ("cli.base_command.Command", "18.1", "9999"),
-                ("basecommand.Command", "7.0.0", "18.0")
+                ("basecommand.Command", "7.0.0", "18.0"),
             ),
             "ConfigOptionParser": (
                 ("cli.parser.ConfigOptionParser", "18.1", "9999"),
-                ("baseparser.ConfigOptionParser", "7.0.0", "18.0")
+                ("baseparser.ConfigOptionParser", "7.0.0", "18.0"),
             ),
             "DistributionNotFound": ("exceptions.DistributionNotFound", "7.0.0", "9999"),
             "FAVORITE_HASH": ("utils.hashes.FAVORITE_HASH", "7.0.0", "9999"),
@@ -80,55 +93,70 @@ class _shims(object):
             ),
             "FrozenRequirement": (
                 ("FrozenRequirement", "7.0.0", "9.0.3"),
-                ("operations.freeze.FrozenRequirement", "10.0.0", "9999")
+                ("operations.freeze.FrozenRequirement", "10.0.0", "9999"),
             ),
             "get_installed_distributions": (
                 ("utils.misc.get_installed_distributions", "10", "9999"),
-                ("utils.get_installed_distributions", "7", "9.0.3")
+                ("utils.get_installed_distributions", "7", "9.0.3"),
             ),
             "index_group": (
                 ("cli.cmdoptions.index_group", "18.1", "9999"),
-                ("cmdoptions.index_group", "7.0.0", "18.0")
+                ("cmdoptions.index_group", "7.0.0", "18.0"),
             ),
             "InstallRequirement": ("req.req_install.InstallRequirement", "7.0.0", "9999"),
             "InstallationError": ("exceptions.InstallationError", "7.0.0", "9999"),
             "UninstallationError": ("exceptions.UninstallationError", "7.0.0", "9999"),
             "DistributionNotFound": ("exceptions.DistributionNotFound", "7.0.0", "9999"),
-            "RequirementsFileParseError": ("exceptions.RequirementsFileParseError", "7.0.0", "9999"),
-            "BestVersionAlreadyInstalled": ("exceptions.BestVersionAlreadyInstalled", "7.0.0", "9999"),
+            "RequirementsFileParseError": (
+                "exceptions.RequirementsFileParseError",
+                "7.0.0",
+                "9999",
+            ),
+            "BestVersionAlreadyInstalled": (
+                "exceptions.BestVersionAlreadyInstalled",
+                "7.0.0",
+                "9999",
+            ),
             "BadCommand": ("exceptions.BadCommand", "7.0.0", "9999"),
             "CommandError": ("exceptions.CommandError", "7.0.0", "9999"),
-            "PreviousBuildDirError": ("exceptions.PreviousBuildDirError", "7.0.0", "9999"),
+            "PreviousBuildDirError": (
+                "exceptions.PreviousBuildDirError",
+                "7.0.0",
+                "9999",
+            ),
             "install_req_from_editable": (
                 ("req.constructors.install_req_from_editable", "18.1", "9999"),
-                ("req.req_install.InstallRequirement.from_editable", "7.0.0", "18.0")
+                ("req.req_install.InstallRequirement.from_editable", "7.0.0", "18.0"),
             ),
             "install_req_from_line": (
                 ("req.constructors.install_req_from_line", "18.1", "9999"),
-                ("req.req_install.InstallRequirement.from_line", "7.0.0", "18.0")
+                ("req.req_install.InstallRequirement.from_line", "7.0.0", "18.0"),
             ),
             "is_archive_file": ("download.is_archive_file", "7.0.0", "9999"),
             "is_file_url": ("download.is_file_url", "7.0.0", "9999"),
             "unpack_url": ("download.unpack_url", "7.0.0", "9999"),
             "is_installable_dir": (
                 ("utils.misc.is_installable_dir", "10.0.0", "9999"),
-                ("utils.is_installable_dir", "7.0.0", "9.0.3")
+                ("utils.is_installable_dir", "7.0.0", "9.0.3"),
             ),
             "Link": ("index.Link", "7.0.0", "9999"),
             "make_abstract_dist": (
                 ("operations.prepare.make_abstract_dist", "10.0.0", "9999"),
-                ("req.req_set.make_abstract_dist", "7.0.0", "9.0.3")
+                ("req.req_set.make_abstract_dist", "7.0.0", "9.0.3"),
             ),
             "make_option_group": (
                 ("cli.cmdoptions.make_option_group", "18.1", "9999"),
-                ("cmdoptions.make_option_group", "7.0.0", "18.0")
+                ("cmdoptions.make_option_group", "7.0.0", "18.0"),
             ),
             "PackageFinder": ("index.PackageFinder", "7.0.0", "9999"),
             "parse_requirements": ("req.req_file.parse_requirements", "7.0.0", "9999"),
-            "parse_version": ("index.parse_version", "7.0.0", "9999"),
             "path_to_url": ("download.path_to_url", "7.0.0", "9999"),
             "PipError": ("exceptions.PipError", "7.0.0", "9999"),
-            "RequirementPreparer": ("operations.prepare.RequirementPreparer", "7", "9999"),
+            "RequirementPreparer": (
+                "operations.prepare.RequirementPreparer",
+                "7",
+                "9999",
+            ),
             "RequirementSet": ("req.req_set.RequirementSet", "7.0.0", "9999"),
             "RequirementTracker": ("req.req_tracker.RequirementTracker", "7.0.0", "9999"),
             "Resolver": ("resolve.Resolver", "7.0.0", "9999"),
@@ -140,10 +168,18 @@ class _shims(object):
             "Wheel": ("wheel.Wheel", "7.0.0", "9999"),
             "WheelCache": (
                 ("cache.WheelCache", "10.0.0", "9999"),
-                ("wheel.WheelCache", "7", "9.0.3")
+                ("wheel.WheelCache", "7", "9.0.3"),
             ),
             "WheelBuilder": ("wheel.WheelBuilder", "7.0.0", "9999"),
             "PyPI": ("models.index.PyPI", "7.0.0", "9999"),
+            "stdlib_pkgs": (
+                ("utils.compat.stdlib_pkgs", "18.1", "9999"),
+                ("compat.stdlib_pkgs", "7", "18.0"),
+            ),
+            "DEV_PKGS": (
+                ("commands.freeze.DEV_PKGS", "9.0.0", "9999"),
+                ({"setuptools", "pip", "distribute", "wheel"}, "7.0.0", "8.1.2"),
+            ),
         }
 
     def _ensure_methods(self, cls, classname, *methods):
@@ -151,6 +187,7 @@ class _shims(object):
         if all(getattr(cls, m, None) for m in method_names):
             return cls
         new_functions = {}
+
         class BaseFunc(Callable):
             def __init__(self, func_base, name, *args, **kwargs):
                 self.func = func_base
@@ -163,11 +200,7 @@ class _shims(object):
             new_functions[method_name] = classmethod(BaseFunc(fn, method_name))
         if six.PY2:
             classname = classname.encode(sys.getdefaultencoding())
-        type_ = type(
-            classname,
-            (cls,),
-            new_functions
-        )
+        type_ = type(classname, (cls,), new_functions)
         return type_
 
     def _get_module_paths(self, module, base_path=None):
@@ -187,22 +220,23 @@ class _shims(object):
         new_to_old = {}
         for method_name, new_method_name in self._moves.get(original_target, {}).items():
             module_paths = self._get_module_paths(new_method_name)
-            target = next(iter(
-                sorted(set([
-                    tgt for mod, tgt in map(self.get_package, module_paths)
-                ]))), None
+            target = next(
+                iter(
+                    sorted(set([tgt for mod, tgt in map(self.get_package, module_paths)]))
+                ),
+                None,
             )
             old_to_new[method_name] = {
                 "target": target,
                 "name": new_method_name,
                 "location": self._locations[new_method_name],
-                "module": self._import(self._locations[new_method_name])
+                "module": self._import(self._locations[new_method_name]),
             }
             new_to_old[new_method_name] = {
                 "target": original_target,
                 "name": method_name,
                 "location": self._locations[original_target],
-                "module": original_import
+                "module": original_import,
             }
         return (old_to_new, new_to_old)
 
@@ -218,9 +252,7 @@ class _shims(object):
                 imported = self._modules[new_target] = new_to_old[new_name]["module"]
             method_map.append((old_method, remapped["module"]))
         if getattr(imported, "__class__", "") == type:
-            imported = self._ensure_methods(
-                imported, new_target, *method_map
-            )
+            imported = self._ensure_methods(imported, new_target, *method_map)
         self._modules[new_target] = imported
         if imported:
             return imported
@@ -231,8 +263,7 @@ class _shims(object):
             self.get_package(pth) for pth in self._get_module_paths(search_pth)
         ]
         moved_methods = [
-            (base, target_cls) for base, target_cls
-            in module_paths if target_cls in moves
+            (base, target_cls) for base, target_cls in module_paths if target_cls in moves
         ]
         return next(iter(moved_methods), None)
 
@@ -280,6 +311,8 @@ class _shims(object):
     def import_module(self, module):
         if module in self._modules:
             return self._modules[module]
+        if not isinstance(module, six.string_types):
+            return module
         try:
             imported = importlib.import_module(module)
         except ImportError:
@@ -299,7 +332,8 @@ class _shims(object):
             for m, package_name in map(self.get_package, modules)
         ]
         imports = [
-            getattr(m, pkg, self.none_or_ctxmanager(pkg)) for pkg, m in modules
+            getattr(m, pkg, self.none_or_ctxmanager(pkg))
+            for pkg, m in modules
             if m is not None
         ]
         return next(iter(imports), None)
@@ -327,15 +361,19 @@ class _shims(object):
     def get_pathinfo(self, module_path):
         assert isinstance(module_path, (list, tuple))
         module_path, start_version, end_version = module_path
-        return self.path_info(module_path, self._parse(start_version), self._parse(end_version))
+        return self.path_info(
+            module_path, self._parse(start_version), self._parse(end_version)
+        )
 
 
 old_module = sys.modules[__name__] if __name__ in sys.modules else None
 module = sys.modules[__name__] = _shims()
-module.__dict__.update({
-    '__file__': __file__,
-    '__package__': __package__,
-    '__doc__': __doc__,
-    '__all__': module.__all__,
-    '__name__': __name__,
-})
+module.__dict__.update(
+    {
+        "__file__": __file__,
+        "__package__": __package__,
+        "__doc__": __doc__,
+        "__all__": module.__all__,
+        "__name__": __name__,
+    }
+)
diff --git a/tasks/__init__.py b/tasks/__init__.py
index a67acd7..c5aaab8 100644
--- a/tasks/__init__.py
+++ b/tasks/__init__.py
@@ -1,48 +1,46 @@
 import pathlib
+import re
 import shutil
 import subprocess
+from pathlib import Path
 
 import invoke
 import parver
-import re
-from pathlib import Path
-
-from towncrier._builder import (
-    find_fragments, render_fragments, split_fragments,
-)
+from towncrier._builder import find_fragments, render_fragments, split_fragments
 from towncrier._settings import load_config
 
-
 ROOT = pathlib.Path(__file__).resolve().parent.parent
 
-PACKAGE_NAME = 'pip_shims'
+PACKAGE_NAME = "pip_shims"
 
-INIT_PY = ROOT.joinpath('src', PACKAGE_NAME, '__init__.py')
+INIT_PY = ROOT.joinpath("src", PACKAGE_NAME, "__init__.py")
 
 
 def _get_git_root(ctx):
-    return Path(ctx.run('git rev-parse --show-toplevel', hide=True).stdout.strip())
+    return Path(ctx.run("git rev-parse --show-toplevel", hide=True).stdout.strip())
 
 
 @invoke.task()
 def clean(ctx):
     """Clean previously built package artifacts.
     """
-    ctx.run(f'python setup.py clean')
-    dist = ROOT.joinpath('dist')
-    print(f'[clean] Removing {dist}')
+    ctx.run(f"python setup.py clean")
+    dist = ROOT.joinpath("dist")
+    print(f"[clean] Removing {dist}")
     if dist.exists():
         shutil.rmtree(str(dist))
 
 
 def _read_version():
-    out = subprocess.check_output(['git', 'tag'], encoding='ascii')
+    out = subprocess.check_output(["git", "tag"], encoding="ascii")
     try:
-        version = max(parver.Version.parse(v).normalize() for v in (
-            line.strip() for line in out.split('\n')
-        ) if v)
+        version = max(
+            parver.Version.parse(v).normalize()
+            for v in (line.strip() for line in out.split("\n"))
+            if v
+        )
     except ValueError:
-        version = parver.Version.parse('0.0.0')
+        version = parver.Version.parse("0.0.0")
     return version
 
 
@@ -50,54 +48,54 @@ def _write_version(v):
     lines = []
     with INIT_PY.open() as f:
         for line in f:
-            if line.startswith('__version__ = '):
-                line = f'__version__ = {repr(str(v))}\n'
+            if line.startswith("__version__ = "):
+                line = f"__version__ = {repr(str(v))}\n".replace("'", '"')
             lines.append(line)
-    with INIT_PY.open('w', newline='\n') as f:
-        f.write(''.join(lines))
+    with INIT_PY.open("w", newline="\n") as f:
+        f.write("".join(lines))
 
 
 def _render_log():
     """Totally tap into Towncrier internals to get an in-memory result.
     """
     config = load_config(ROOT)
-    definitions = config['types']
+    definitions = config["types"]
     fragments, fragment_filenames = find_fragments(
-        pathlib.Path(config['directory']).absolute(),
-        config['sections'],
+        pathlib.Path(config["directory"]).absolute(),
+        config["sections"],
         None,
         definitions,
     )
     rendered = render_fragments(
-        pathlib.Path(config['template']).read_text(encoding='utf-8'),
-        config['issue_format'],
+        pathlib.Path(config["template"]).read_text(encoding="utf-8"),
+        config["issue_format"],
         split_fragments(fragments, definitions),
         definitions,
-        config['underlines'][1:],
+        config["underlines"][1:],
         False,  # Don't add newlines to wrapped text.
     )
     return rendered
 
 
-REL_TYPES = ('major', 'minor', 'patch',)
+REL_TYPES = ("major", "minor", "patch")
 
 
 def _bump_release(version, type_):
     if type_ not in REL_TYPES:
-        raise ValueError(f'{type_} not in {REL_TYPES}')
+        raise ValueError(f"{type_} not in {REL_TYPES}")
     index = REL_TYPES.index(type_)
-    next_version = version.base_version().bump_release(index)
-    print(f'[bump] {version} -> {next_version}')
+    next_version = version.base_version().bump_release(index=index)
+    print(f"[bump] {version} -> {next_version}")
     return next_version
 
 
 def _prebump(version, prebump):
-    next_version = version.bump_release(prebump).bump_dev()
-    print(f'[bump] {version} -> {next_version}')
+    next_version = version.bump_release(index=prebump).bump_dev()
+    print(f"[bump] {version} -> {next_version}")
     return next_version
 
 
-PREBUMP = 'patch'
+PREBUMP = "patch"
 
 
 @invoke.task(pre=[clean])
@@ -105,7 +103,7 @@ def release(ctx, type_, repo, prebump=PREBUMP):
     """Make a new release.
     """
     if prebump not in REL_TYPES:
-        raise ValueError(f'{type_} not in {REL_TYPES}')
+        raise ValueError(f"{type_} not in {REL_TYPES}")
     prebump = REL_TYPES.index(prebump)
 
     version = _read_version()
@@ -115,26 +113,26 @@ def release(ctx, type_, repo, prebump=PREBUMP):
     # Needs to happen before Towncrier deletes fragment files.
     tag_content = _render_log()
 
-    # ctx.run('towncrier')
+    ctx.run("towncrier")
 
     ctx.run(f'git commit -am "Release {version}"')
 
     tag_content = tag_content.replace('"', '\\"')
     ctx.run(f'git tag -a {version} -m "Version {version}\n\n{tag_content}"')
 
-    ctx.run(f'python setup.py sdist bdist_wheel')
+    ctx.run(f"python setup.py sdist bdist_wheel")
 
     dist_pattern = f'{PACKAGE_NAME.replace("-", "[-_]")}-*'
-    artifacts = list(ROOT.joinpath('dist').glob(dist_pattern))
-    filename_display = '\n'.join(f'  {a}' for a in artifacts)
-    print(f'[release] Will upload:\n{filename_display}')
+    artifacts = list(ROOT.joinpath("dist").glob(dist_pattern))
+    filename_display = "\n".join(f"  {a}" for a in artifacts)
+    print(f"[release] Will upload:\n{filename_display}")
     try:
-        input('[release] Release ready. ENTER to upload, CTRL-C to abort: ')
+        input("[release] Release ready. ENTER to upload, CTRL-C to abort: ")
     except KeyboardInterrupt:
-        print('\nAborted!')
+        print("\nAborted!")
         return
 
-    arg_display = ' '.join(f'"{n}"' for n in artifacts)
+    arg_display = " ".join(f'"{n}"' for n in artifacts)
     ctx.run(f'twine upload --repository="{repo}" {arg_display}')
 
     version = _prebump(version, prebump)
@@ -147,9 +145,9 @@ def release(ctx, type_, repo, prebump=PREBUMP):
 def build_docs(ctx):
     _current_version = _read_version()
     minor = [str(i) for i in parver.Version.parse(_current_version).release[:2]]
-    docs_folder = (_get_git_root(ctx) / 'docs').as_posix()
-    if not docs_folder.endswith('/'):
-        docs_folder = '{0}/'.format(docs_folder)
+    docs_folder = (_get_git_root(ctx) / "docs").as_posix()
+    if not docs_folder.endswith("/"):
+        docs_folder = "{0}/".format(docs_folder)
     args = ["--ext-autodoc", "--ext-viewcode", "-o", docs_folder]
     args.extend(["-A", "'Dan Ryan <dan@danryan.co>'"])
     args.extend(["-R", _current_version])
@@ -163,5 +161,10 @@ def build_docs(ctx):
 def clean_mdchangelog(ctx):
     changelog = ROOT / "CHANGELOG.md"
     content = changelog.read_text()
-    content = re.sub(r"([^\n]+)\n?\s+\[[\\]+(#\d+)\]\(https://github\.com/sarugaku/[\w\-]+/issues/\d+\)", r"\1 \2", content, flags=re.MULTILINE)
+    content = re.sub(
+        r"([^\n]+)\n?\s+\[[\\]+(#\d+)\]\(https://github\.com/sarugaku/[\w\-]+/issues/\d+\)",
+        r"\1 \2",
+        content,
+        flags=re.MULTILINE,
+    )
     changelog.write_text(content)

Add shim for commands.freeze.DEV_PKGS and utils.compat.stdlib_pkgs
pip-tools uses both of these
diff --git a/tests/test_instances.py b/tests/test_instances.py
index 0d02c96..0eddd19 100644
--- a/tests/test_instances.py
+++ b/tests/test_instances.py
@@ -396,3 +396,13 @@ def test_wheelbuilder(tmpdir, PipCommand):
 
 def test_pypi():
     assert "pypi.org" in PyPI.url or "pypi.python.org" in PyPI.url
+
+
+def test_dev_pkgs():
+    from pip_shims.shims import DEV_PKGS
+    assert "pip" in DEV_PKGS and "wheel" in DEV_PKGS
+
+
+def test_stdlib_pkgs():
+    from pip_shims.shims import stdlib_pkgs
+    assert "argparse" in stdlib_pkgs

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-timeout pip setuptools wheel
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
packaging==24.2
-e git+https://github.com/sarugaku/pip-shims.git@15d6e4d405a779c7ca5a976576fef5c0054569ec#egg=pip_shims
pluggy==1.5.0
pytest==8.3.5
pytest-cov==6.0.0
pytest-timeout==2.3.1
six==1.17.0
tomli==2.2.1

name: pip-shims
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - packaging==24.2
      - pip-shims==0.3.3.dev0
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - pytest-timeout==2.3.1
      - six==1.17.0
      - tomli==2.2.1
prefix: /opt/conda/envs/pip-shims

tests/test_instances.py::test_stdlib_pkgs
tests/test_instances.py::test_command tests/test_instances.py::test_configparser tests/test_instances.py::test_exceptions[None-Exception] tests/test_instances.py::test_get_installed tests/test_instances.py::test_link_and_ireq tests/test_instances.py::test_path_and_url tests/test_instances.py::test_cache_dir tests/test_instances.py::test_parse_version tests/test_instances.py::test_archive_file tests/test_instances.py::test_pip_version tests/test_instances.py::test_resolution tests/test_instances.py::test_abstract_dist tests/test_instances.py::test_safe_file_cache tests/test_instances.py::test_wheel_cache tests/test_instances.py::test_vcs_support tests/test_instances.py::test_wheel tests/test_instances.py::test_wheelbuilder tests/test_instances.py::test_dev_pkgs
tests/test_instances.py::test_strip_extras tests/test_instances.py::test_cmdoptions tests/test_instances.py::test_exceptions[DistributionNotFound-Exception0] tests/test_instances.py::test_exceptions[PipError-Exception] tests/test_instances.py::test_exceptions[InstallationError-Exception] tests/test_instances.py::test_exceptions[DistributionNotFound-Exception1] tests/test_instances.py::test_exceptions[RequirementsFileParseError-Exception] tests/test_instances.py::test_exceptions[BestVersionAlreadyInstalled-Exception] tests/test_instances.py::test_exceptions[BadCommand-Exception] tests/test_instances.py::test_exceptions[CommandError-Exception] tests/test_instances.py::test_exceptions[PreviousBuildDirError-Exception] tests/test_instances.py::test_favorite_hash tests/test_instances.py::test_format_control tests/test_instances.py::test_is_installable tests/test_instances.py::test_frozen_req tests/test_instances.py::test_pypi
README.rst docs/quickstart.rst tasks/__init__.py news/25.feature.rst Pipfile.lock pyproject.toml setup.cfg Pipfile .pre-commit-config.yaml src/pip_shims/shims.py
README.rst docs/quickstart.rst tasks/__init__.py news/25.feature.rst Pipfile.lock pyproject.toml setup.cfg Pipfile .pre-commit-config.yaml src/pip_shims/shims.py