diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-08-04 15:47:11 +0200 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-08-04 17:05:58 +0200 |
commit | 6760eb76e665dc81863a82110164c4b3b38e7ee9 (patch) | |
tree | 3a9cf1606c851ad4067c2419fec78e7f6ca044ac | |
parent | ded036cf988b0cf4b20002d88434282f30762638 (diff) | |
download | rsa-git-6760eb76e665dc81863a82110164c4b3b38e7ee9.tar.gz |
Added mypy for static type checking
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Pipfile | 3 | ||||
-rw-r--r-- | Pipfile.lock | 54 | ||||
-rw-r--r-- | rsa/cli.py | 10 | ||||
-rw-r--r-- | setup.cfg | 13 | ||||
-rw-r--r-- | tests/test_cli.py | 40 | ||||
-rw-r--r-- | tests/test_mypy.py | 27 | ||||
-rw-r--r-- | tox.ini | 3 |
8 files changed, 119 insertions, 32 deletions
@@ -12,6 +12,7 @@ .coverage .coverage.* .cache/ +.mypy_cache/ .pytest_cache/ __pycache__/ @@ -13,7 +13,8 @@ Sphinx = "*" coveralls = "*" pytest = "*" pytest-cov = "*" -pathlib2 = {version = "*", markers="python_version < '3.6'"} +pathlib2 = {version = "*",markers = "python_version < '3.6'"} +mypy = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 6a399e6..9ec9947 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "65309370bad59af42cbf3b538e9a050dece94209b8b9657eb4e9f1ca8feedda4" + "sha256": "376fdc997e7b1f113fdc6c27ce5d1ba88f01a3dbe64f03d54132e5f7b5cd24a4" }, "pipfile-spec": 6, "requires": { @@ -210,6 +210,30 @@ ], "version": "==7.2.0" }, + "mypy": { + "hashes": [ + "sha256:0107bff4f46a289f0e4081d59b77cef1c48ea43da5a0dbf0005d54748b26df2a", + "sha256:07957f5471b3bb768c61f08690c96d8a09be0912185a27a68700f3ede99184e4", + "sha256:10af62f87b6921eac50271e667cc234162a194e742d8e02fc4ddc121e129a5b0", + "sha256:11fd60d2f69f0cefbe53ce551acf5b1cec1a89e7ce2d47b4e95a84eefb2899ae", + "sha256:15e43d3b1546813669bd1a6ec7e6a11d2888db938e0607f7b5eef6b976671339", + "sha256:352c24ba054a89bb9a35dd064ee95ab9b12903b56c72a8d3863d882e2632dc76", + "sha256:437020a39417e85e22ea8edcb709612903a9924209e10b3ec6d8c9f05b79f498", + "sha256:49925f9da7cee47eebf3420d7c0e00ec662ec6abb2780eb0a16260a7ba25f9c4", + "sha256:6724fcd5777aa6cebfa7e644c526888c9d639bd22edd26b2a8038c674a7c34bd", + "sha256:7a17613f7ea374ab64f39f03257f22b5755335b73251d0d253687a69029701ba", + "sha256:cdc1151ced496ca1496272da7fc356580e95f2682be1d32377c22ddebdf73c91" + ], + "index": "pypi", + "version": "==0.720" + }, + "mypy-extensions": { + "hashes": [ + "sha256:37e0e956f41369209a3d5f34580150bcacfabaa57b33a15c0b25f4b5725e0812", + "sha256:b16cabe759f55e3409a7d231ebd2841378fb0c27a5d1994719e340e4f429ac3e" + ], + "version": "==0.4.1" + }, "packaging": { "hashes": [ "sha256:a7ac867b97fdc07ee80a8058fe4435ccd274ecc3b0ed61d852d7d53055528cf9", @@ -362,6 +386,34 @@ "index": "pypi", "version": "==3.13.2" }, + "typed-ast": { + "hashes": [ + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "version": "==1.4.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:2ed632b30bb54fc3941c382decfd0ee4148f5c591651c9272473fea2c6397d95", + "sha256:b1edbbf0652660e32ae780ac9433f4231e7339c7f9a8057d0f042fcbcea49b87", + "sha256:d8179012ec2c620d3791ca6fe2bf7979d979acdbef1fca0bc56b37411db682ed" + ], + "version": "==3.7.4" + }, "urllib3": { "hashes": [ "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", @@ -21,9 +21,11 @@ These scripts are called by the executables defined in setup.py. import abc import sys +import typing from optparse import OptionParser import rsa +import rsa.key import rsa.pkcs1 HASH_METHODS = sorted(rsa.pkcs1.HASH_METHODS.keys()) @@ -84,14 +86,12 @@ def keygen(): sys.stdout.buffer.write(data) -class CryptoOperation(object): +class CryptoOperation(metaclass=abc.ABCMeta): """CLI callable that operates with input, output, and a key.""" - __metaclass__ = abc.ABCMeta - keyname = 'public' # or 'private' usage = 'usage: %%prog [options] %(keyname)s_key' - description = None + description = '' operation = 'decrypt' operation_past = 'decrypted' operation_progressive = 'decrypting' @@ -102,7 +102,7 @@ class CryptoOperation(object): expected_cli_args = 1 has_output = True - key_class = rsa.PublicKey + key_class = rsa.PublicKey # type: typing.Type[rsa.key.AbstractKey] def __init__(self): self.usage = self.usage % self.__class__.__dict__ @@ -3,3 +3,16 @@ universal = 1 [metadata] license_file = LICENSE + +[flake8] +max-line-length = 100 + +[pep8] +max-line-length = 100 + +[mypy] +python_version = 3.7 +warn_unused_ignores = True +ignore_missing_imports = True +follow_imports = skip +incremental = True diff --git a/tests/test_cli.py b/tests/test_cli.py index 7cf7ed4..1cd92c2 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,41 +4,37 @@ Unit tests for CLI entry points. from __future__ import print_function -import unittest -import sys import functools -from contextlib import contextmanager - +import io import os -from io import StringIO, BytesIO +import sys +import typing +import unittest +from contextlib import contextmanager, redirect_stdout, redirect_stderr import rsa import rsa.cli import rsa.util -def make_buffer() -> StringIO: - buf = StringIO() - buf.buffer = BytesIO() - return buf +@contextmanager +def captured_output() -> typing.Generator: + """Captures output to stdout and stderr""" + # According to mypy, we're not supposed to change buf_out.buffer. + # However, this is just a test, and it works, hence the 'type: ignore'. + buf_out = io.StringIO() + buf_out.buffer = io.BytesIO() # type: ignore -def get_bytes_out(out: StringIO) -> bytes: - # Python 3.x writes 'bytes' to stdout.buffer - return out.buffer.getvalue() + buf_err = io.StringIO() + buf_err.buffer = io.BytesIO() # type: ignore + with redirect_stdout(buf_out), redirect_stderr(buf_err): + yield buf_out, buf_err -@contextmanager -def captured_output(): - """Captures output to stdout and stderr""" - new_out, new_err = make_buffer(), make_buffer() - old_out, old_err = sys.stdout, sys.stderr - try: - sys.stdout, sys.stderr = new_out, new_err - yield new_out, new_err - finally: - sys.stdout, sys.stderr = old_out, old_err +def get_bytes_out(buf) -> bytes: + return buf.buffer.getvalue() @contextmanager diff --git a/tests/test_mypy.py b/tests/test_mypy.py new file mode 100644 index 0000000..c2a9745 --- /dev/null +++ b/tests/test_mypy.py @@ -0,0 +1,27 @@ +import pathlib +import unittest + +import mypy.api + +test_modules = ['rsa', 'tests'] + + +class MypyRunnerTest(unittest.TestCase): + def test_run_mypy(self): + proj_root = pathlib.Path(__file__).parent.parent + args = ['--incremental', '--ignore-missing-imports'] + [str(proj_root / dirname) for dirname + in test_modules] + + result = mypy.api.run(args) + + stdout, stderr, status = result + + messages = [] + if stderr: + messages.append(stderr) + if stdout: + messages.append(stdout) + if status: + messages.append('Mypy failed with status %d' % status) + if messages: + self.fail('\n'.join(['Mypy errors:'] + messages)) @@ -15,6 +15,3 @@ commands= commands= pipenv install --dev --ignore-pipfile pipenv run py.test --doctest-modules rsa tests - -[pep8] -max-line-length = 100 |