Skip to content

Commit 89c15b7

Browse files
author
David Robertson
authored
Merge pull request #20 from matrix-org/dmr/linting
Linting and broadcast type annotations
2 parents 629c026 + 867486d commit 89c15b7

11 files changed

Lines changed: 120 additions & 64 deletions

File tree

.flake8

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Ideally this would be in pyproject.toml, but that's not possible right now. See
2+
# https://github.com/PyCQA/flake8/issues/234
3+
# https://github.com/johnthagen/python-blueprint/issues/29#issuecomment-1003437646
4+
[flake8]
5+
# see https://pycodestyle.readthedocs.io/en/latest/intro.html#error-codes
6+
# and https://flake8.pycqa.org/en/latest/user/error-codes.html
7+
# for error codes. The ones we ignore are:
8+
# W503: line break before binary operator
9+
# W504: line break after binary operator
10+
# E203: whitespace before ':' (which is contrary to pep8?)
11+
# E731: do not assign a lambda expression, use a def
12+
# E501: Line too long (black enforces this for us)
13+
ignore=W503,W504,E203,E731,E501
14+
exclude=dist,.venv

pyproject.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,21 @@
3333
directory = "misc"
3434
name = "Internal Changes"
3535
showcontent = true
36+
37+
[tool.isort]
38+
line_length = 88
39+
multi_line_output = 3
40+
include_trailing_comma = true
41+
combine_as_imports = true
42+
known_first_party = ["signedjson", "tests"]
43+
44+
[tool.black]
45+
# Placeholder for now.
46+
47+
[tool.mypy]
48+
files = ["signedjson", "tests"]
49+
show_error_codes = true
50+
51+
[[tool.mypy.overrides]]
52+
module = ["canonicaljson"]
53+
ignore_missing_imports = true

setup.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
from setuptools import setup
18-
from codecs import open
1917
import os
18+
from codecs import open
19+
20+
from setuptools import setup
2021

2122
here = os.path.abspath(os.path.dirname(__file__))
2223

@@ -48,4 +49,7 @@ def read_file(path_segments):
4849
},
4950
long_description=read_file(("README.rst",)),
5051
keywords="json",
52+
package_data={
53+
"signedjson": ["py.typed"]
54+
}
5155
)

signedjson/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
# limitations under the License.
1414

1515
try:
16-
from importlib.metadata import version, PackageNotFoundError
16+
from importlib.metadata import PackageNotFoundError, version
1717
except ImportError: # pragma: nocover
18-
from importlib_metadata import version, PackageNotFoundError
18+
from importlib_metadata import ( # type: ignore[import, no-redef]
19+
PackageNotFoundError,
20+
version,
21+
)
1922

2023
try:
2124
__version__ = version(__name__)

signedjson/key.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import nacl.signing
2121
from unpaddedbase64 import decode_base64, encode_base64
2222

23-
from signedjson.types import SigningKey, VerifyKey
23+
from signedjson.types import SigningKey, VerifyKey, VerifyKeyWithExpiry
2424

2525
NACL_ED25519 = "ed25519"
2626
SUPPORTED_ALGORITHMS = [NACL_ED25519]
@@ -34,7 +34,7 @@ def generate_signing_key(version):
3434
Returns:
3535
A SigningKey object.
3636
"""
37-
key = nacl.signing.SigningKey.generate()
37+
key: SigningKey = nacl.signing.SigningKey.generate() # type: ignore[assignment]
3838
key.version = version
3939
key.alg = NACL_ED25519
4040
return key
@@ -43,7 +43,7 @@ def generate_signing_key(version):
4343
def get_verify_key(signing_key):
4444
# type: (SigningKey) -> VerifyKey
4545
"""Get a verify key from a signing key"""
46-
verify_key = signing_key.verify_key
46+
verify_key: VerifyKey = signing_key.verify_key # type: ignore[assignment]
4747
verify_key.version = signing_key.version
4848
verify_key.alg = signing_key.alg
4949
return verify_key
@@ -61,7 +61,7 @@ def decode_signing_key_base64(algorithm, version, key_base64):
6161
"""
6262
if algorithm == NACL_ED25519:
6363
key_bytes = decode_base64(key_base64)
64-
key = nacl.signing.SigningKey(key_bytes)
64+
key: SigningKey = nacl.signing.SigningKey(key_bytes) # type: ignore[assignment]
6565
key.version = version
6666
key.alg = NACL_ED25519
6767
return key
@@ -125,8 +125,8 @@ def decode_verify_key_bytes(key_id, key_bytes):
125125
A VerifyKey object.
126126
"""
127127
if key_id.startswith(NACL_ED25519 + ":"):
128-
version = key_id[len(NACL_ED25519) + 1:]
129-
key = nacl.signing.VerifyKey(key_bytes)
128+
version = key_id[len(NACL_ED25519) + 1 :]
129+
key: VerifyKey = nacl.signing.VerifyKey(key_bytes) # type: ignore[assignment]
130130
key.version = version
131131
key.alg = NACL_ED25519
132132
return key
@@ -151,7 +151,7 @@ def read_signing_keys(stream):
151151

152152

153153
def read_old_signing_keys(stream):
154-
# type: (Iterable[str]) -> List[VerifyKey]
154+
# type: (Iterable[str]) -> List[VerifyKeyWithExpiry]
155155
"""Reads a list of old keys from a stream
156156
Args:
157157
stream : A stream to iterate for keys.
@@ -161,7 +161,9 @@ def read_old_signing_keys(stream):
161161
keys = []
162162
for line in stream:
163163
algorithm, version, expired, key_base64 = line.split()
164-
key = decode_verify_key_base64(algorithm, version, key_base64)
164+
key: VerifyKeyWithExpiry = decode_verify_key_base64(
165+
algorithm, version, key_base64
166+
) # type: ignore[assignment]
165167
key.expired = int(expired)
166168
keys.append(key)
167169
return keys
@@ -176,4 +178,11 @@ def write_signing_keys(stream, keys):
176178
"""
177179
for key in keys:
178180
key_base64 = encode_signing_key_base64(key)
179-
stream.write("%s %s %s\n" % (key.alg, key.version, key_base64,))
181+
stream.write(
182+
"%s %s %s\n"
183+
% (
184+
key.alg,
185+
key.version,
186+
key_base64,
187+
)
188+
)

signedjson/py.typed

Whitespace-only changes.

signedjson/sign.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ def sign_json(json_object, signature_name, signing_key):
6161
return json_object
6262

6363

64-
def signature_ids(json_object, signature_name,
65-
supported_algorithms=SUPPORTED_ALGORITHMS):
64+
def signature_ids(
65+
json_object, signature_name, supported_algorithms=SUPPORTED_ALGORITHMS
66+
):
6667
# type: (JsonDict, str, Iterable[str]) -> List[str]
6768
"""Does the JSON object have a signature for the given name?
6869
Args:
@@ -75,13 +76,13 @@ def signature_ids(json_object, signature_name,
7576
"""
7677
key_ids = json_object.get("signatures", {}).get(signature_name, {}).keys()
7778
return list(
78-
key_id for key_id in key_ids
79-
if key_id.split(":")[0] in supported_algorithms
79+
key_id for key_id in key_ids if key_id.split(":")[0] in supported_algorithms
8080
)
8181

8282

8383
class SignatureVerifyException(Exception):
8484
"""A signature could not be verified"""
85+
8586
pass
8687

8788

@@ -131,7 +132,10 @@ def verify_signed_json(json_object, signature_name, verify_key):
131132
verify_key.verify(message, signature)
132133
except Exception as e:
133134
raise SignatureVerifyException(
134-
"Unable to verify signature for %s: %s %s" % (
135-
signature_name, type(e), e,
135+
"Unable to verify signature for %s: %s %s"
136+
% (
137+
signature_name,
138+
type(e),
139+
e,
136140
)
137141
)

signedjson/types.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,35 @@
2626

2727
class BaseKey(Protocol):
2828
"""Common base type for VerifyKey and SigningKey"""
29+
2930
version = "" # type: str
3031
alg = "" # type: str
3132

3233
def encode(self):
3334
# type: () -> bytes
34-
pass # pragma: nocover
35+
pass # pragma: nocover
3536

3637

3738
class VerifyKey(BaseKey):
3839
"""The public part of a key pair, for use with verify_signed_json"""
40+
3941
def verify(self, message, signature):
4042
# type: (bytes, bytes) -> bytes
41-
pass # pragma: nocover
43+
pass # pragma: nocover
44+
45+
46+
class VerifyKeyWithExpiry(VerifyKey):
47+
expired: int
4248

4349

4450
class SigningKey(BaseKey):
4551
"""The private part of a key pair, for use with sign_json"""
52+
4653
def sign(self, message):
4754
# type: (bytes) -> nacl.signing.SignedMessage
48-
pass # pragma: nocover
55+
pass # pragma: nocover
4956

5057
@property
5158
def verify_key(self):
5259
# type: () -> nacl.signing.VerifyKey
53-
pass # pragma: nocover
60+
pass # pragma: nocover

tests/test_key.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class GenerateTestCase(unittest.TestCase):
1919
def test_generate_key(self):
2020
my_version = "my_version"
2121
my_key = generate_signing_key(my_version)
22-
self.assertEqual(my_key.alg, 'ed25519')
22+
self.assertEqual(my_key.alg, "ed25519")
2323
self.assertEqual(my_key.version, my_version)
2424

2525

@@ -35,7 +35,7 @@ def test_decode(self):
3535
decoded_key = decode_signing_key_base64(
3636
"ed25519", self.version, self.key_base64
3737
)
38-
self.assertEqual(decoded_key.alg, 'ed25519')
38+
self.assertEqual(decoded_key.alg, "ed25519")
3939
self.assertEqual(decoded_key.version, self.version)
4040

4141
def test_decode_invalid_base64(self):
@@ -54,7 +54,7 @@ def test_decode_verify_key(self):
5454
decoded_key = decode_verify_key_base64(
5555
"ed25519", self.version, self.verify_key_base64
5656
)
57-
self.assertEqual(decoded_key.alg, 'ed25519')
57+
self.assertEqual(decoded_key.alg, "ed25519")
5858
self.assertEqual(decoded_key.version, self.version)
5959

6060
def test_decode_verify_key_invalid_base64(self):

tests/test_known_key.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,21 @@
1616

1717
import unittest
1818

19-
from unpaddedbase64 import decode_base64
20-
2119
import nacl.signing
20+
from unpaddedbase64 import decode_base64
2221

2322
from signedjson.sign import sign_json
2423

25-
SIGNING_KEY_SEED = decode_base64(
26-
"YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA1"
27-
)
24+
SIGNING_KEY_SEED = decode_base64("YJDBA9Xnr2sVqXD9Vj7XVUnmFZcZrlw8Md7kMW+3XA1")
2825

2926
KEY_ALG = "ed25519"
3027
KEY_VER = 1
3128
KEY_NAME = "%s:%d" % (KEY_ALG, KEY_VER)
3229

3330

3431
class KnownKeyTestCase(unittest.TestCase):
35-
""" An entirely deterministic test using a given signing key seed, so that
36-
other implementations can compare that they get the same result. """
32+
"""An entirely deterministic test using a given signing key seed, so that
33+
other implementations can compare that they get the same result."""
3734

3835
def setUp(self):
3936
self.signing_key = nacl.signing.SigningKey(SIGNING_KEY_SEED)
@@ -44,26 +41,26 @@ def test_sign_minimal(self):
4441
self.assertEqual(
4542
sign_json({}, "domain", self.signing_key),
4643
{
47-
'signatures': {
48-
'domain': {
44+
"signatures": {
45+
"domain": {
4946
KEY_NAME: "K8280/U9SSy9IVtjBuVeLr+HpOB4BQFWbg+UZaADMt"
5047
"TdGYI7Geitb76LTrr5QV/7Xg4ahLwYGYZzuHGZKM5ZAQ"
5148
},
5249
}
53-
}
50+
},
5451
)
5552

5653
def test_sign_with_data(self):
5754
self.assertEqual(
58-
sign_json({'one': 1, 'two': "Two"}, "domain", self.signing_key),
55+
sign_json({"one": 1, "two": "Two"}, "domain", self.signing_key),
5956
{
60-
'one': 1,
61-
'two': "Two",
62-
'signatures': {
63-
'domain': {
57+
"one": 1,
58+
"two": "Two",
59+
"signatures": {
60+
"domain": {
6461
KEY_NAME: "KqmLSbO39/Bzb0QIYE82zqLwsA+PDzYIpIRA2sRQ4s"
6562
"L53+sN6/fpNSoqE7BP7vBZhG6kYdD13EIMJpvhJI+6Bw"
6663
},
67-
}
68-
}
64+
},
65+
},
6966
)

0 commit comments

Comments
 (0)