Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type annotations #341

Merged
merged 8 commits into from Aug 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -7,3 +7,4 @@ omit=
precision = 1
exclude_lines =
pragma: no cover
if TYPE_CHECKING:
22 changes: 22 additions & 0 deletions .github/workflows/lint.yml
@@ -0,0 +1,22 @@
name: Lint

on:
push:
branches-ignore:
- "dependabot/**"
pull_request:

jobs:
Lint:
name: 'Lint'
timeout-minutes: 10
runs-on: 'ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Run lint
run: ./lint.sh
6 changes: 6 additions & 0 deletions lint-requirements.in
@@ -0,0 +1,6 @@
# Typing
mypy[python2]==0.910
# TODO: Switch to cryptography>=35.0.0 once it's released.
types-cryptography>=3.3.3
types-pyopenssl>=20.0.4
py>=1.9.0
28 changes: 28 additions & 0 deletions lint-requirements.txt
@@ -0,0 +1,28 @@
#
# This file is autogenerated by pip-compile with python 3.9
# To update, run:
#
# pip-compile lint-requirements.in
#
mypy[python2]==0.910
# via -r lint-requirements.in
mypy-extensions==0.4.3
# via mypy
py==1.10.0
# via -r lint-requirements.in
toml==0.10.2
# via mypy
typed-ast==1.4.3
# via mypy
types-cryptography==3.3.3
# via
# -r lint-requirements.in
# types-pyopenssl
types-enum34==0.1.8
# via types-cryptography
types-ipaddress==0.1.5
# via types-cryptography
types-pyopenssl==20.0.4
# via -r lint-requirements.in
typing-extensions==3.10.0.0
# via mypy
17 changes: 17 additions & 0 deletions lint.sh
@@ -0,0 +1,17 @@
#!/bin/bash

set -exu -o pipefail

python -c "import sys, struct, ssl; print('#' * 70); print('python:', sys.version); print('version_info:', sys.version_info); print('bits:', struct.calcsize('P') * 8); print('openssl:', ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO); print('#' * 70)"

python -m pip install -U pip setuptools wheel
python -m pip --version

# Dependencies

python -m pip install -Ur lint-requirements.txt

# Linting

mypy trustme tests
mypy -2 trustme tests
1 change: 1 addition & 0 deletions newsfragments/339.feature.rst
@@ -0,0 +1 @@
The package is now type annotated. If you use mypy on code which uses ``trustme``, you should be able to remove any exclusions.
23 changes: 23 additions & 0 deletions pyproject.toml
Expand Up @@ -17,3 +17,26 @@ directory = "newsfragments"
underlines = ["-", "~", "^"]
# Requires https://github.com/hawkowl/towncrier/pull/66
issue_format = "`#{issue} <https://github.com/python-trio/trustme/issues/{issue}>`__"

[tool.mypy]
check_untyped_defs = true
disallow_any_generics = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
no_implicit_optional = true
no_implicit_reexport = true
show_error_codes = true
strict_equality = true
warn_redundant_casts = true
warn_return_any = true
warn_unreachable = true
warn_unused_configs = true
# Some ignores are only for python2/python3.
# warn_unused_ignores = true

[[tool.mypy.overrides]]
module = "pytest"
ignore_missing_imports = true
3 changes: 3 additions & 0 deletions setup.py
Expand Up @@ -13,6 +13,9 @@
author_email="njs@pobox.com",
license="MIT -or- Apache License 2.0",
packages=find_packages(),
package_data={
'trustme': ['py.typed'],
},
url="https://github.com/python-trio/trustme",
install_requires=[
"cryptography",
Expand Down
15 changes: 15 additions & 0 deletions tests/test_cli.py
Expand Up @@ -3,12 +3,18 @@
import subprocess
import sys

import py
import pytest

from trustme._cli import main

TYPE_CHECKING = False
if TYPE_CHECKING: # pragma: no cover
from typing import Any


def test_trustme_cli(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
main(argv=[])

Expand All @@ -18,6 +24,7 @@ def test_trustme_cli(tmpdir):


def test_trustme_cli_e2e(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
rv = subprocess.call([sys.executable, "-m", "trustme"])
assert rv == 0
Expand All @@ -28,6 +35,7 @@ def test_trustme_cli_e2e(tmpdir):


def test_trustme_cli_directory(tmpdir):
# type: (py.path.local) -> None
subdir = tmpdir.mkdir("sub")
main(argv=["-d", str(subdir)])

Expand All @@ -37,12 +45,14 @@ def test_trustme_cli_directory(tmpdir):


def test_trustme_cli_directory_does_not_exist(tmpdir):
# type: (py.path.local) -> None
notdir = tmpdir.join("notdir")
with pytest.raises(ValueError, match="is not a directory"):
main(argv=["-d", str(notdir)])


def test_trustme_cli_identities(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
main(argv=["-i", "example.org", "www.example.org"])

Expand All @@ -52,11 +62,13 @@ def test_trustme_cli_identities(tmpdir):


def test_trustme_cli_identities_empty(tmpdir):
# type: (py.path.local) -> None
with pytest.raises(ValueError, match="at least one identity"):
main(argv=["-i"])


def test_trustme_cli_common_name(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
main(argv=["--common-name", "localhost"])

Expand All @@ -66,6 +78,7 @@ def test_trustme_cli_common_name(tmpdir):


def test_trustme_cli_expires_on(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
main(argv=["--expires-on", "2035-03-01"])

Expand All @@ -75,6 +88,7 @@ def test_trustme_cli_expires_on(tmpdir):


def test_trustme_cli_invalid_expires_on(tmpdir):
# type: (py.path.local) -> None
with tmpdir.as_cwd():
with pytest.raises(ValueError, match="does not match format"):
main(argv=["--expires-on", "foobar"])
Expand All @@ -85,6 +99,7 @@ def test_trustme_cli_invalid_expires_on(tmpdir):


def test_trustme_cli_quiet(capsys, tmpdir):
# type: (Any, py.path.local) -> None
with tmpdir.as_cwd():
main(argv=["-q"])

Expand Down