diff --git a/src/Pipfile b/src/Pipfile index 1c81e1a00..e0bd5956d 100644 --- a/src/Pipfile +++ b/src/Pipfile @@ -24,3 +24,4 @@ black = "*" flake8 = "*" mypy = "*" types-requests = "*" +django-stubs = "*" diff --git a/src/Pipfile.lock b/src/Pipfile.lock index 1f80d0797..d70a4fa2e 100644 --- a/src/Pipfile.lock +++ b/src/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "45645e181d935b55c0d58e163245cce64c11cfbcc86ad9cbb2d549d613d9069e" + "sha256": "4a80654b3a48bad09447fe8adb85f07f0df9be3b3c8b37341d5741b4dd919957" }, "pipfile-spec": 6, "requires": {}, @@ -30,11 +30,11 @@ }, "certifi": { "hashes": [ - "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5", - "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516" + "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", + "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" ], "markers": "python_version >= '3.6'", - "version": "==2022.9.14" + "version": "==2022.9.24" }, "cfenv": { "hashes": [ @@ -170,10 +170,10 @@ }, "dj-email-url": { "hashes": [ - "sha256:64257c4f9d8139a4af8e5267229d32260e433fbf257b0cf8fc855bb0cc39ca7d", - "sha256:ef36f8a324ec57cf3be5c7a7ef44ed6900ca0208624a918ab33adc1cf6427b39" + "sha256:55ffe3329e48f54f8a75aa36ece08f365e09d61f8a209773ef09a1d4760e699a", + "sha256:cbd08327fbb08b104eac160fb4703f375532e4c0243eb230f5b960daee7a96db" ], - "version": "==1.0.5" + "version": "==1.0.6" }, "django": { "hashes": [ @@ -249,11 +249,11 @@ }, "mako": { "hashes": [ - "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f", - "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534" + "sha256:7fde96466fcfeedb0eed94f187f20b23d85e4cb41444be0e542e2c8c65c396cd", + "sha256:c413a086e38cd885088d5e165305ee8eed04e8b3f8f62df343480da0a385735f" ], "markers": "python_version >= '3.7'", - "version": "==1.2.2" + "version": "==1.2.3" }, "markupsafe": { "hashes": [ @@ -303,11 +303,11 @@ }, "marshmallow": { "hashes": [ - "sha256:1172ce82765bf26c24a3f9299ed6dbeeca4d213f638eaa39a37772656d7ce408", - "sha256:48e2d88d4ab431ad5a17c25556d9da529ea6e966876f2a38d274082e270287f0" + "sha256:35e02a3a06899c9119b785c12a22f4cda361745d66a71ab691fd7610202ae104", + "sha256:6804c16114f7fce1f5b4dadc31f4674af23317fcc7f075da21e35c1a35d781f7" ], "markers": "python_version >= '3.7'", - "version": "==3.17.1" + "version": "==3.18.0" }, "oic": { "hashes": [ @@ -349,6 +349,7 @@ "sha256:1f6b813106a3abdf7b03640d36e24669234120c72e91d5cbaeb87c5f7c36c65b", "sha256:280b0bb5cbfe8039205c7981cceb006156a675362a00fe29b16fbc264e242834", "sha256:2d872e3c9d5d075a2e104540965a1cf898b52274a5923936e5bfddb58c59c7c2", + "sha256:2f2534ab7dc7e776a263b463a16e189eb30e85ec9bbe1bff9e78dae802608932", "sha256:2f9ffd643bc7349eeb664eba8864d9e01f057880f510e4681ba40a6532f93c71", "sha256:3303f8807f342641851578ee7ed1f3efc9802d00a6f83c101d21c608cb864460", "sha256:35168209c9d51b145e459e05c31a9eaeffa9a6b0fd61689b48e07464ffd1a83e", @@ -381,6 +382,7 @@ "sha256:adf20d9a67e0b6393eac162eb81fb10bc9130a80540f4df7e7355c2dd4af9fba", "sha256:af9813db73395fb1fc211bac696faea4ca9ef53f32dc0cfa27e4e7cf766dcf24", "sha256:b1c8068513f5b158cf7e29c43a77eb34b407db29aca749d3eb9293ee0d3103ca", + "sha256:b3a24a1982ae56461cc24f6680604fffa2c1b818e9dc55680da038792e004d18", "sha256:bda845b664bb6c91446ca9609fc69f7db6c334ec5e4adc87571c34e4f47b7ddb", "sha256:c381bda330ddf2fccbafab789d83ebc6c53db126e4383e73794c74eedce855ef", "sha256:c3ae8e75eb7160851e59adc77b3a19a976e50622e44fd4fd47b8b18208189d42", @@ -388,6 +390,7 @@ "sha256:def68d7c21984b0f8218e8a15d514f714d96904265164f75f8d3a70f9c295667", "sha256:dffc08ca91c9ac09008870c9eb77b00a46b3378719584059c034b8945e26b272", "sha256:e3699852e22aa68c10de06524a3721ade969abf382da95884e6a10ff798f9281", + "sha256:e6aa71ae45f952a2205377773e76f4e3f27951df38e69a4c95440c779e013560", "sha256:e847774f8ffd5b398a75bc1c18fbb56564cda3d629fe68fd81971fece2d3c67e", "sha256:ffb7a888a047696e7f8240d649b43fb3644f14f0ee229077e7f6b9f9081635bd" ], @@ -470,11 +473,11 @@ }, "setuptools": { "hashes": [ - "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", - "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" + "sha256:a8f6e213b4b0661f590ccf40de95d28a177cd747d098624ad3f69c40287297e9", + "sha256:c2d2709550f15aab6c9110196ea312f468f41cd546bceb24127a1be6fdcaeeb1" ], "markers": "python_version >= '3.7'", - "version": "==65.3.0" + "version": "==65.4.0" }, "six": { "hashes": [ @@ -486,11 +489,11 @@ }, "sqlparse": { "hashes": [ - "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae", - "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d" + "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34", + "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268" ], "markers": "python_version >= '3.5'", - "version": "==0.4.2" + "version": "==0.4.3" }, "typing-extensions": { "hashes": [ @@ -589,11 +592,27 @@ }, "django-debug-toolbar": { "hashes": [ - "sha256:95fc2fd29c56cc86678aae9f6919ececefe892f2a78c4004b193a223a8380c3d", - "sha256:fe7fe3f21865218827e2162ecc06eba386dfe8cffe4f3501c49bb4359e06a0e6" + "sha256:1e3acad24e3d351ba45c6fa2072e4164820307332a776b16c9f06d1f89503465", + "sha256:80de23066b624d3970fd296cf02d61988e5d56c31aa0dc4a428970b46e2883a8" ], "index": "pypi", - "version": "==3.6.0" + "version": "==3.7.0" + }, + "django-stubs": { + "hashes": [ + "sha256:0dff8ec0ba3abe046450b3d8a29ce9e72629893d2c1ef679189cc2bfdb6d2f64", + "sha256:ea8b35d0da49f7b2ee99a79125f1943e033431dd114726d6643cc35de619230e" + ], + "index": "pypi", + "version": "==1.12.0" + }, + "django-stubs-ext": { + "hashes": [ + "sha256:9bd7418376ab00b7f88d6d56be9fece85bfa0c7c348ac621155fa4d7a91146f2", + "sha256:c5d8db53d29c756e7e3d0820a5a079a43bc38d8fab0e1b8bd5df2f3366c54b5a" + ], + "markers": "python_version >= '3.6'", + "version": "==0.5.0" }, "flake8": { "hashes": [ @@ -629,32 +648,33 @@ }, "mypy": { "hashes": [ - "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655", - "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9", - "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3", - "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6", - "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0", - "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58", - "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103", - "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09", - "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417", - "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56", - "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2", - "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856", - "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0", - "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8", - "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27", - "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5", - "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71", - "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27", - "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe", - "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca", - "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf", - "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9", - "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c" + "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", + "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", + "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", + "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", + "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", + "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", + "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", + "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", + "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", + "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", + "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", + "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", + "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", + "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", + "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", + "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", + "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", + "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", + "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", + "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", + "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", + "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", + "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", + "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" ], "index": "pypi", - "version": "==0.971" + "version": "==0.981" }, "mypy-extensions": { "hashes": [ @@ -775,11 +795,11 @@ }, "sqlparse": { "hashes": [ - "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae", - "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d" + "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34", + "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268" ], "markers": "python_version >= '3.5'", - "version": "==0.4.2" + "version": "==0.4.3" }, "stevedore": { "hashes": [ @@ -797,20 +817,34 @@ "markers": "python_full_version < '3.11.0a7'", "version": "==2.0.1" }, + "types-pytz": { + "hashes": [ + "sha256:47cfb19c52b9f75896440541db392fd312a35b279c6307a531db71152ea63e2b", + "sha256:50ead2254b524a3d4153bc65d00289b66898060d2938e586170dce918dbaf3b3" + ], + "version": "==2022.2.1.0" + }, + "types-pyyaml": { + "hashes": [ + "sha256:29228db9f82df4f1b7febee06bbfb601677882e98a3da98132e31c6874163e15", + "sha256:f6f350418125872f3f0409d96a62a5a5ceb45231af5cc07ee0034ec48a3c82fa" + ], + "version": "==6.0.12" + }, "types-requests": { "hashes": [ - "sha256:45b485725ed58752f2b23461252f1c1ad9205b884a1e35f786bb295525a3e16a", - "sha256:97d8f40aa1ffe1e58c3726c77d63c182daea9a72d9f1fa2cafdea756b2a19f2c" + "sha256:7ee827eb8ce611b02b5117cfec5da6455365b6a575f5e3ff19f655ba603e6b4e", + "sha256:af5f55e803cabcfb836dad752bd6d8a0fc8ef1cd84243061c0e27dee04ccf4fd" ], "index": "pypi", - "version": "==2.28.10" + "version": "==2.28.11" }, "types-urllib3": { "hashes": [ - "sha256:a1b3aaea7dda3eb1b51699ee723aadd235488e4dc4648e030f09bc429ecff42f", - "sha256:cf7918503d02d3576e503bbfb419b0e047c4617653bba09624756ab7175e15c9" + "sha256:5aef0e663724eef924afa8b320b62ffef2c1736c1fa6caecfc9bc6c8ae2c3def", + "sha256:c1d78cef7bd581e162e46c20a57b2e1aa6ebecdcf01fd0713bb90978ff3e3427" ], - "version": "==1.26.24" + "version": "==1.26.25" }, "typing-extensions": { "hashes": [ diff --git a/src/djangooidc/oidc.py b/src/djangooidc/oidc.py index afcd7ee7e..f4ce070f9 100644 --- a/src/djangooidc/oidc.py +++ b/src/djangooidc/oidc.py @@ -7,7 +7,7 @@ import json from django.conf import settings from django.http import HttpResponseRedirect from Cryptodome.PublicKey.RSA import importKey -from jwkest.jwk import RSAKey +from jwkest.jwk import RSAKey # type: ignore from oic import oic, rndstr from oic.oauth2 import ErrorResponse from oic.oic import AuthorizationRequest, AuthorizationResponse, RegistrationResponse diff --git a/src/mypy.ini b/src/mypy.ini new file mode 100644 index 000000000..5f4ec24aa --- /dev/null +++ b/src/mypy.ini @@ -0,0 +1,7 @@ +[mypy] +plugins = + mypy_django_plugin.main +strict_optional = True + +[mypy.plugins.django-stubs] +django_settings_module = "registrar.config.settings" diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 0840fc948..cda2f14bc 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -18,7 +18,7 @@ $ docker-compose exec app python manage.py shell """ import environs from base64 import b64decode -from cfenv import AppEnv +from cfenv import AppEnv # type: ignore from pathlib import Path # # # ### diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 54454c2aa..0a9ff6da9 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -23,7 +23,7 @@ urlpatterns = [ # was actually True. Instead, let's add these URLs any time we are able to # import the debug toolbar package. try: - import debug_toolbar + import debug_toolbar # type: ignore urlpatterns += [path("__debug__/", include(debug_toolbar.urls))] except ImportError: diff --git a/src/registrar/management/commands/lint.py b/src/registrar/management/commands/lint.py index 964c63098..34975b8e6 100644 --- a/src/registrar/management/commands/lint.py +++ b/src/registrar/management/commands/lint.py @@ -3,6 +3,10 @@ from subprocess import run, CalledProcessError # nosec from django.core.management.base import BaseCommand, CommandError +class LinterError(Exception): + pass + + class Command(BaseCommand): """ Helper command for running installed linters. @@ -41,6 +45,7 @@ class Command(BaseCommand): def handle(self, *args, **options): try: + errors = [] for linter in self.linters.values(): self.stdout.write(f"[manage.py lint] {linter['purpose']}. . .") result = run(linter["args"]) @@ -51,12 +56,15 @@ class Command(BaseCommand): f"{' '.join(linter['args'])}" ) ) - break + errors.append(CalledProcessError(result.returncode, linter["args"])) else: self.stdout.write( f"[manage.py lint] {linter['purpose']} completed with success!" ) - except CalledProcessError as e: + if errors: + self.stdout.write(f"[manage.py lint] {len(errors)} linter(s) failed.") + raise LinterError(errors) + except (CalledProcessError, LinterError) as e: raise CommandError(e) self.stdout.write( self.style.SUCCESS("[manage.py lint] All linters ran successfully.")