diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c1d5647..4e28eab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,19 @@ jobs: - uses: actions/checkout@v2 - name: Black Check uses: jpetrucciani/black-check@20.8b1 + mypy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: "3.9" + - uses: Gr1N/setup-poetry@v4 + - run: poetry install + - run: poetry run mypy --py2 sysaudit/ tests/ + name: Mypy Check Python2 + - run: poetry run mypy sysaudit/ tests/ + name: Mypy Check Python3 test: runs-on: ubuntu-latest strategy: diff --git a/poetry.lock b/poetry.lock index 982ed89..3ad7437 100644 --- a/poetry.lock +++ b/poetry.lock @@ -177,6 +177,22 @@ category = "dev" optional = false python-versions = ">=3.5" +[[package]] +name = "mypy" +version = "0.800" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +mypy-extensions = ">=0.4.3,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" + +[package.extras] +dmypy = ["psutil (>=4.0)"] + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -314,6 +330,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "typing" +version = "3.7.4.3" +description = "Type Hints for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + [[package]] name = "typing-extensions" version = "3.7.4.3" @@ -351,7 +375,7 @@ testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"] [metadata] lock-version = "1.1" python-versions = "~2.7 || ~=3.5" -content-hash = "0c50ae6c648ef29d97374fa76541950369bf55f54f8bc3fe6e4df19b9d500638" +content-hash = "fe83468734284b10f0b424dab2cf20729e7feab41eac731cc1b7e86b4accc4f1" [metadata.files] appdirs = [ @@ -449,6 +473,30 @@ more-itertools = [ {file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"}, {file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"}, ] +mypy = [ + {file = "mypy-0.800-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:e1c84c65ff6d69fb42958ece5b1255394714e0aac4df5ffe151bc4fe19c7600a"}, + {file = "mypy-0.800-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:947126195bfe4709c360e89b40114c6746ae248f04d379dca6f6ab677aa07641"}, + {file = "mypy-0.800-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:b95068a3ce3b50332c40e31a955653be245666a4bc7819d3c8898aa9fb9ea496"}, + {file = "mypy-0.800-cp35-cp35m-win_amd64.whl", hash = "sha256:ca7ad5aed210841f1e77f5f2f7d725b62c78fa77519312042c719ed2ab937876"}, + {file = "mypy-0.800-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e32b7b282c4ed4e378bba8b8dfa08e1cfa6f6574067ef22f86bee5b1039de0c9"}, + {file = "mypy-0.800-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e497a544391f733eca922fdcb326d19e894789cd4ff61d48b4b195776476c5cf"}, + {file = "mypy-0.800-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:5615785d3e2f4f03ab7697983d82c4b98af5c321614f51b8f1034eb9ebe48363"}, + {file = "mypy-0.800-cp36-cp36m-win_amd64.whl", hash = "sha256:2b216eacca0ec0ee124af9429bfd858d5619a0725ee5f88057e6e076f9eb1a7b"}, + {file = "mypy-0.800-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e3b8432f8df19e3c11235c4563a7250666dc9aa7cdda58d21b4177b20256ca9f"}, + {file = "mypy-0.800-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d16c54b0dffb861dc6318a8730952265876d90c5101085a4bc56913e8521ba19"}, + {file = "mypy-0.800-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0d2fc8beb99cd88f2d7e20d69131353053fbecea17904ee6f0348759302c52fa"}, + {file = "mypy-0.800-cp37-cp37m-win_amd64.whl", hash = "sha256:aa9d4901f3ee1a986a3a79fe079ffbf7f999478c281376f48faa31daaa814e86"}, + {file = "mypy-0.800-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:319ee5c248a7c3f94477f92a729b7ab06bf8a6d04447ef3aa8c9ba2aa47c6dcf"}, + {file = "mypy-0.800-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:74f5aa50d0866bc6fb8e213441c41e466c86678c800700b87b012ed11c0a13e0"}, + {file = "mypy-0.800-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a301da58d566aca05f8f449403c710c50a9860782148332322decf73a603280b"}, + {file = "mypy-0.800-cp38-cp38-win_amd64.whl", hash = "sha256:b9150db14a48a8fa114189bfe49baccdff89da8c6639c2717750c7ae62316738"}, + {file = "mypy-0.800-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5fdf935a46aa20aa937f2478480ebf4be9186e98e49cc3843af9a5795a49a25"}, + {file = "mypy-0.800-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6f8425fecd2ba6007e526209bb985ce7f49ed0d2ac1cc1a44f243380a06a84fb"}, + {file = "mypy-0.800-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:5ff616787122774f510caeb7b980542a7cc2222be3f00837a304ea85cd56e488"}, + {file = "mypy-0.800-cp39-cp39-win_amd64.whl", hash = "sha256:90b6f46dc2181d74f80617deca611925d7e63007cf416397358aa42efb593e07"}, + {file = "mypy-0.800-py3-none-any.whl", hash = "sha256:3e0c159a7853e3521e3f582adb1f3eac66d0b0639d434278e2867af3a8c62653"}, + {file = "mypy-0.800.tar.gz", hash = "sha256:e0202e37756ed09daf4b0ba64ad2c245d357659e014c3f51d8cd0681ba66940a"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, @@ -577,6 +625,10 @@ typed-ast = [ {file = "typed_ast-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440"}, {file = "typed_ast-1.4.2.tar.gz", hash = "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a"}, ] +typing = [ + {file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"}, + {file = "typing-3.7.4.3.tar.gz", hash = "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9"}, +] typing-extensions = [ {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, diff --git a/pyproject.toml b/pyproject.toml index ba8508f..eca6311 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,8 @@ Cython = "^0.29.21" black = {version = "^20.8b1", python = "~=3.6"} pytest = {version = "~=4.6"} mock = "~=3.0" +mypy = {version = "~=0.800", python = "~=3.5"} +typing = {version = "~=3.7.4", python = "~=2.7"} [build-system] requires = ["poetry-core>=1.0.0", "Cython", "setuptools"] diff --git a/sysaudit/__init__.pyi b/sysaudit/__init__.pyi new file mode 100644 index 0000000..cd66550 --- /dev/null +++ b/sysaudit/__init__.pyi @@ -0,0 +1,6 @@ +import typing + +def audit(event: str, *args: typing.Any) -> None: ... +def addaudithook( + hook: typing.Callable[[str, typing.Tuple[typing.Any, ...]], None] +) -> None: ... diff --git a/sysaudit/_csysaudit.pyi b/sysaudit/_csysaudit.pyi new file mode 100644 index 0000000..cd66550 --- /dev/null +++ b/sysaudit/_csysaudit.pyi @@ -0,0 +1,6 @@ +import typing + +def audit(event: str, *args: typing.Any) -> None: ... +def addaudithook( + hook: typing.Callable[[str, typing.Tuple[typing.Any, ...]], None] +) -> None: ... diff --git a/sysaudit/py.typed b/sysaudit/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/tests/audit-tests.py b/tests/audit-tests.py index 99e00f0..4358408 100644 --- a/tests/audit-tests.py +++ b/tests/audit-tests.py @@ -6,6 +6,7 @@ module with arguments identifying each test. """ import contextlib +import typing import sys import sysaudit @@ -24,7 +25,7 @@ class TestHook: self.seen = [] self.closed = False - def __enter__(self, *a): + def __enter__(self, *a): # type: (typing.Any) -> TestHook sysaudit.addaudithook(self) return self @@ -38,7 +39,9 @@ class TestHook: def seen_events(self): return [i[0] for i in self.seen] - def __call__(self, event, args): + def __call__( + self, event, args + ): # type: (str, typing.Tuple[typing.Any, ...]) -> None if self.closed: return self.seen.append((event, args)) @@ -246,12 +249,12 @@ def test_mmap(): assertEqual(hook.seen[0][1][:2], (-1, 8)) -def test_excepthook(): +def test_excepthook(): # type: () -> None def excepthook(exc_type, exc_value, exc_tb): if exc_type is not RuntimeError: sys.__excepthook__(exc_type, exc_value, exc_tb) - def hook(event, args): + def hook(event, args): # type: (str, typing.Tuple[typing.Any, ...]) -> None if event == "sys.excepthook": if not isinstance(args[2], args[1]): raise TypeError( @@ -266,27 +269,27 @@ def test_excepthook(): raise RuntimeError("fatal-error") -def test_unraisablehook(): - from _testcapi import write_unraisable_exc +def test_unraisablehook(): # type: () -> None + from _testcapi import write_unraisable_exc # type: ignore def unraisablehook(hookargs): pass - def hook(event, args): + def hook(event, args): # type: (str, typing.Tuple[typing.Any, ...]) -> None if event == "sys.unraisablehook": if args[0] != unraisablehook: raise ValueError("Expected {} == {}".format(args[0], unraisablehook)) print(event, repr(args[1].exc_value), args[1].err_msg) sysaudit.addaudithook(hook) - sys.unraisablehook = unraisablehook + sys.unraisablehook = unraisablehook # type: ignore [attr-defined] write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None) -def test_winreg(): - from winreg import OpenKey, EnumKey, CloseKey, HKEY_LOCAL_MACHINE +def test_winreg(): # type: () -> None + from winreg import OpenKey, EnumKey, CloseKey, HKEY_LOCAL_MACHINE # type: ignore - def hook(event, args): + def hook(event, args): # type: (str, typing.Tuple[typing.Any, ...]) -> None if not event.startswith("winreg."): return print(event, args) @@ -306,10 +309,10 @@ def test_winreg(): CloseKey(kv) -def test_socket(): +def test_socket(): # type: () -> None import socket - def hook(event, args): + def hook(event, args): # type: (str, typing.Tuple[typing.Any, ...]) -> None if event.startswith("socket."): print(event, args) diff --git a/tests/test_import.py b/tests/test_import.py index 064b148..7842bf5 100644 --- a/tests/test_import.py +++ b/tests/test_import.py @@ -3,10 +3,10 @@ import sys import sysaudit -def test_module(): +def test_module(): # type: () -> None if sys.version_info >= (3, 8, 0): - assert sysaudit.audit == sys.audit - assert sysaudit.addaudithook == sys.addaudithook + assert sysaudit.audit == sys.audit # type: ignore [attr-defined] + assert sysaudit.addaudithook == sys.addaudithook # type: ignore [attr-defined] else: assert sysaudit.audit == sysaudit._csysaudit.audit assert sysaudit.addaudithook == sysaudit._csysaudit.addaudithook