Skip to content

Commit

Permalink
Add mypy to CI (#693)
Browse files Browse the repository at this point in the history
* Configure mypy

Use the lightweight config from
    https://github.com/pyca/cryptography/blob/main/pyproject.toml#L24
for now.

* Run mypy in CI

* Annotate attributes of Signed and EncryptedMessage

placeholder for now, to get mypy passing

* Address mypy's warnings about missing `__bytes__`

Sadly I can't import `SupportBytes` from typing_extensions, so for 3.8
and below I need to define it myself.

* Distinguish builtin exceptions from nacl's clones

* Only require mypy or testing on cpython

* Fix a couple of typos

* Can use stdlib's `SupportBytes`

* Mypy is not a package dependency

* Typecheck in a dedicated tox env

* Appease the linter
  • Loading branch information
DMRobertson authored Nov 2, 2021
1 parent ee93f9f commit ea0db5f
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 8 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
PYTHON:
- {VERSION: "3.9", TOXENV: "docs", COVERAGE: "false"}
- {VERSION: "3.9", TOXENV: "meta", COVERAGE: "false"}
- {VERSION: "3.9", TOXENV: "mypy", COVERAGE: "false"}
- {VERSION: "pypy3", TOXENV: "pypy"}
- {VERSION: "3.6", TOXENV: "py36"}
- {VERSION: "3.7", TOXENV: "py37"}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ src/libsodium/libtool

# whitelist libsodium's build directory
!src/libsodium/builds/msvc/build

# mypy's cache
.mypy_cache
13 changes: 13 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,16 @@ build-backend = "setuptools.build_meta"
[tool.black]
line-length = 79
target-version = ["py36"]

[tool.mypy]
show_error_codes = true
check_untyped_defs = true
no_implicit_reexport = true

files = ["src/nacl"]

[[tool.mypy.overrides]]
module = [
"nacl._sodium",
]
ignore_missing_imports = true
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@

requirements = []
setup_requirements = ["setuptools"]
test_requirements = ["pytest>=3.2.1,!=3.3.0", "hypothesis>=3.27.0"]
test_requirements = [
"pytest>=3.2.1,!=3.3.0",
"hypothesis>=3.27.0",
]
docs_requirements = ["sphinx>=1.6.5", "sphinx_rtd_theme"]


Expand Down
3 changes: 2 additions & 1 deletion src/nacl/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import base64
import binascii
from typing import SupportsBytes


class RawEncoder:
Expand Down Expand Up @@ -78,5 +79,5 @@ def decode(data):


class Encodable:
def encode(self, encoder=RawEncoder):
def encode(self: SupportsBytes, encoder=RawEncoder):
return encoder.encode(bytes(self))
15 changes: 11 additions & 4 deletions src/nacl/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
# limitations under the License.


# We create a clone of various builtin Exception types which additionally
# inherit from CryptoError. Below, we refer to the parent types via the
# `builtins` namespace, so mypy can distinguish between (e.g.)
# `nacl.exceptions.RuntimeError` and `builtins.RuntimeError`.
import builtins


class CryptoError(Exception):
"""
Base exception for all nacl related errors
Expand All @@ -25,19 +32,19 @@ class BadSignatureError(CryptoError):
"""


class RuntimeError(RuntimeError, CryptoError):
class RuntimeError(builtins.RuntimeError, CryptoError):
pass


class AssertionError(AssertionError, CryptoError):
class AssertionError(builtins.AssertionError, CryptoError):
pass


class TypeError(TypeError, CryptoError):
class TypeError(builtins.TypeError, CryptoError):
pass


class ValueError(ValueError, CryptoError):
class ValueError(builtins.ValueError, CryptoError):
pass


Expand Down
3 changes: 3 additions & 0 deletions src/nacl/signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class SignedMessage(bytes):
:class:`SigningKey`.
"""

_signature: object
_message: object

@classmethod
def _from_parts(cls, signature, message, combined):
obj = cls(combined)
Expand Down
6 changes: 5 additions & 1 deletion src/nacl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


import os
from typing import SupportsBytes

import nacl.bindings
from nacl import encoding
Expand All @@ -25,6 +26,9 @@ class EncryptedMessage(bytes):
:class:`SecretBox`.
"""

_nonce = object
_ciphertext = object

@classmethod
def _from_parts(cls, nonce, ciphertext, combined):
obj = cls(combined)
Expand All @@ -48,7 +52,7 @@ def ciphertext(self):


class StringFixer:
def __str__(self):
def __str__(self: SupportsBytes):
return str(self.__bytes__())


Expand Down
8 changes: 7 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = pypy,py36,py37,py38,docs,meta
envlist = pypy,py36,py37,py38,docs,meta,mypy
isolated_build = True

[testenv]
Expand Down Expand Up @@ -37,6 +37,12 @@ commands =
black --check .
check-manifest . --ignore .travis.yml

[testenv:mypy]
deps =
mypy
commands =
mypy

[flake8]
ignore = E203,E501,W503,W504
select = E,W,F,I
Expand Down

0 comments on commit ea0db5f

Please sign in to comment.