Skip to content

Commit 6c58946

Browse files
committed
convert all attrs classes to use custom init methods to enable mypy to work #4
1 parent 6515bbf commit 6c58946

File tree

19 files changed

+587
-39
lines changed

19 files changed

+587
-39
lines changed

src/dynamodb_encryption_sdk/delegated_keys/jce.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
from cryptography.hazmat.primitives.asymmetric import rsa
2323
import six
2424

25+
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
26+
from typing import Dict, Optional, Text # noqa pylint: disable=unused-import
27+
except ImportError: # pragma: no cover
28+
# We only actually need these imports when running the mypy checks
29+
pass
30+
2531
from dynamodb_encryption_sdk.exceptions import JceTransformationError, UnwrappingError
2632
from dynamodb_encryption_sdk.identifiers import EncryptionKeyType, KeyEncodingType, LOGGER_NAME
2733
from dynamodb_encryption_sdk.internal.crypto.jce_bridge import authentication, encryption, primitives
@@ -67,7 +73,7 @@ def _generate_rsa_key(key_length):
6773
}
6874

6975

70-
@attr.s
76+
@attr.s(init=False)
7177
class JceNameLocalDelegatedKey(DelegatedKey):
7278
# pylint: disable=too-many-instance-attributes
7379
"""Delegated key that uses JCE StandardName algorithm values to determine behavior.
@@ -114,6 +120,25 @@ class JceNameLocalDelegatedKey(DelegatedKey):
114120
_key_type = attr.ib(validator=attr.validators.instance_of(EncryptionKeyType))
115121
_key_encoding = attr.ib(validator=attr.validators.instance_of(KeyEncodingType))
116122

123+
def __init__(
124+
self,
125+
key, # type: bytes
126+
algorithm, # type: Text
127+
key_type, # type: EncryptionKeyType
128+
key_encoding # type: KeyEncodingType
129+
):
130+
# type: (...) -> None
131+
"""Workaround pending resolution of attrs/mypy interaction.
132+
https://github.com/python/mypy/issues/2088
133+
https://github.com/python-attrs/attrs/issues/215
134+
"""
135+
self.key = key
136+
self._algorithm = algorithm
137+
self._key_type = key_type
138+
self._key_encoding = key_encoding
139+
attr.validate(self)
140+
self.__attrs_post_init__()
141+
117142
@property
118143
def algorithm(self):
119144
# type: () -> Text

src/dynamodb_encryption_sdk/encrypted/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
__all__ = ('CryptoConfig',)
3131

3232

33-
@attr.s
33+
@attr.s(init=False)
3434
class CryptoConfig(object):
3535
"""Container for all configuration needed to encrypt or decrypt an item.
3636
@@ -46,6 +46,23 @@ class CryptoConfig(object):
4646
encryption_context = attr.ib(validator=attr.validators.instance_of(EncryptionContext))
4747
attribute_actions = attr.ib(validator=attr.validators.instance_of(AttributeActions))
4848

49+
def __init__(
50+
self,
51+
materials_provider, # type: CryptographicMaterialsProvider
52+
encryption_context, # type: EncryptionContext
53+
attribute_actions # type: AttributeActions
54+
):
55+
# type: (...) -> None
56+
"""Workaround pending resolution of attrs/mypy interaction.
57+
https://github.com/python/mypy/issues/2088
58+
https://github.com/python-attrs/attrs/issues/215
59+
"""
60+
self.materials_provider = materials_provider
61+
self.encryption_context = encryption_context
62+
self.attribute_actions = attribute_actions
63+
attr.validate(self)
64+
self.__attrs_post_init__()
65+
4966
def __attrs_post_init__(self):
5067
# type: () -> None
5168
"""Make sure that primary index attributes are not being encrypted."""

src/dynamodb_encryption_sdk/encrypted/client.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
import attr
1717
import botocore
1818

19+
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
20+
from typing import Any, Callable, Dict, Optional # noqa pylint: disable=unused-import
21+
except ImportError: # pragma: no cover
22+
# We only actually need these imports when running the mypy checks
23+
pass
24+
1925
from dynamodb_encryption_sdk.internal.utils import (
2026
crypto_config_from_cache, crypto_config_from_kwargs,
2127
decrypt_batch_get_item, decrypt_get_item, decrypt_multi_get,
@@ -30,7 +36,7 @@
3036
__all__ = ('EncryptedClient',)
3137

3238

33-
@attr.s
39+
@attr.s(init=False)
3440
class EncryptedPaginator(object):
3541
"""Paginator that decrypts returned items before returning them.
3642
@@ -44,6 +50,22 @@ class EncryptedPaginator(object):
4450
_decrypt_method = attr.ib()
4551
_crypto_config_method = attr.ib(validator=callable_validator)
4652

53+
def __init__(
54+
self,
55+
paginator, # type: botocore.paginate.Paginator
56+
decrypt_method, # type: Callable
57+
crypto_config_method # type: Callable
58+
):
59+
# type: (...) -> None
60+
"""Workaround pending resolution of attrs/mypy interaction.
61+
https://github.com/python/mypy/issues/2088
62+
https://github.com/python-attrs/attrs/issues/215
63+
"""
64+
self._paginator = paginator
65+
self._decrypt_method = decrypt_method
66+
self._crypto_config_method = crypto_config_method
67+
attr.validate(self)
68+
4769
@_decrypt_method.validator
4870
def validate_decrypt_method(self, attribute, value):
4971
# pylint: disable=unused-argument
@@ -84,7 +106,7 @@ def paginate(self, **kwargs):
84106
yield page
85107

86108

87-
@attr.s
109+
@attr.s(init=False)
88110
class EncryptedClient(object):
89111
# pylint: disable=too-few-public-methods,too-many-instance-attributes
90112
"""High-level helper class to provide a familiar interface to encrypted tables.
@@ -143,6 +165,30 @@ class EncryptedClient(object):
143165
default=False
144166
)
145167

168+
def __init__(
169+
self,
170+
client, # type: botocore.client.BaseClient
171+
materials_provider, # type: CryptographicMaterialsProvider
172+
attribute_actions=None, # type: Optional[AttributeActions]
173+
auto_refresh_table_indexes=True, # type: Optional[bool]
174+
expect_standard_dictionaries=False # type: Optional[bool]
175+
):
176+
# type: (...) -> None
177+
"""Workaround pending resolution of attrs/mypy interaction.
178+
https://github.com/python/mypy/issues/2088
179+
https://github.com/python-attrs/attrs/issues/215
180+
"""
181+
if attribute_actions is None:
182+
attribute_actions = AttributeActions()
183+
184+
self._client = client
185+
self._materials_provider = materials_provider
186+
self._attribute_actions = attribute_actions
187+
self._auto_refresh_table_indexes = auto_refresh_table_indexes
188+
self._expect_standard_dictionaries = expect_standard_dictionaries
189+
attr.validate(self)
190+
self.__attrs_post_init__()
191+
146192
def __attrs_post_init__(self):
147193
"""Set up the table info cache and translation methods."""
148194
if self._expect_standard_dictionaries:

src/dynamodb_encryption_sdk/encrypted/resource.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
__all__ = ('EncryptedResource',)
2929

3030

31-
@attr.s
31+
@attr.s(init=False)
3232
class EncryptedTablesCollectionManager(object):
3333
# pylint: disable=too-few-public-methods
3434
"""Tables collection manager that provides EncryptedTable objects.
@@ -50,6 +50,25 @@ class EncryptedTablesCollectionManager(object):
5050
_attribute_actions = attr.ib(validator=attr.validators.instance_of(AttributeActions))
5151
_table_info_cache = attr.ib(validator=attr.validators.instance_of(TableInfoCache))
5252

53+
def __init__(
54+
self,
55+
collection, # type: CollectionManager
56+
materials_provider, # type: CryptographicMaterialsProvider
57+
attribute_actions, # type: AttributeActions
58+
table_info_cache # type: TableInfoCache
59+
):
60+
# type: (...) -> None
61+
"""Workaround pending resolution of attrs/mypy interaction.
62+
https://github.com/python/mypy/issues/2088
63+
https://github.com/python-attrs/attrs/issues/215
64+
"""
65+
self._collection = collection
66+
self._materials_provider = materials_provider
67+
self._attribute_actions = attribute_actions
68+
self._table_info_cache = table_info_cache
69+
attr.validate(self)
70+
self.__attrs_post_init__()
71+
5372
def __attrs_post_init__(self):
5473
"""Set up the translation methods."""
5574
self.all = partial( # attrs confuses pylint: disable=attribute-defined-outside-init
@@ -95,7 +114,7 @@ def _transform_table(self, method, **kwargs):
95114
)
96115

97116

98-
@attr.s
117+
@attr.s(init=False)
99118
class EncryptedResource(object):
100119
# pylint: disable=too-few-public-methods
101120
"""High-level helper class to provide a familiar interface to encrypted tables.
@@ -142,6 +161,28 @@ class EncryptedResource(object):
142161
default=True
143162
)
144163

164+
def __init__(
165+
self,
166+
resource, # type: ServiceResource
167+
materials_provider, # type: CryptographicMaterialsProvider
168+
attribute_actions=None, # type: Optional[AttributeActions]
169+
auto_refresh_table_indexes=True # type: Optional[bool]
170+
):
171+
# type: (...) -> None
172+
"""Workaround pending resolution of attrs/mypy interaction.
173+
https://github.com/python/mypy/issues/2088
174+
https://github.com/python-attrs/attrs/issues/215
175+
"""
176+
if attribute_actions is None:
177+
attribute_actions = AttributeActions()
178+
179+
self._resource = resource
180+
self._materials_provider = materials_provider
181+
self._attribute_actions = attribute_actions
182+
self._auto_refresh_table_indexes = auto_refresh_table_indexes
183+
attr.validate(self)
184+
self.__attrs_post_init__()
185+
145186
def __attrs_post_init__(self):
146187
"""Set up the table info cache, encrypted tables collection manager, and translation methods."""
147188
self._table_info_cache = TableInfoCache( # attrs confuses pylint: disable=attribute-defined-outside-init

src/dynamodb_encryption_sdk/encrypted/table.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
__all__ = ('EncryptedTable',)
3030

3131

32-
@attr.s
32+
@attr.s(init=False)
3333
class EncryptedTable(object):
3434
# pylint: disable=too-few-public-methods
3535
"""High-level helper class to provide a familiar interface to encrypted tables.
@@ -86,6 +86,30 @@ class EncryptedTable(object):
8686
default=True
8787
)
8888

89+
def __init__(
90+
self,
91+
table, # type: ServiceResource
92+
materials_provider, # type: CryptographicMaterialsProvider
93+
table_info=None, # type: Optional[TableInfo]
94+
attribute_actions=None, # type: Optional[AttributeActions]
95+
auto_refresh_table_indexes=True # type: Optional[bool]
96+
):
97+
# type: (...) -> None
98+
"""Workaround pending resolution of attrs/mypy interaction.
99+
https://github.com/python/mypy/issues/2088
100+
https://github.com/python-attrs/attrs/issues/215
101+
"""
102+
if attribute_actions is None:
103+
attribute_actions = AttributeActions()
104+
105+
self._table = table
106+
self._materials_provider = materials_provider
107+
self._table_info = table_info
108+
self._attribute_actions = attribute_actions
109+
self._auto_refresh_table_indexes = auto_refresh_table_indexes
110+
attr.validate(self)
111+
self.__attrs_post_init__()
112+
89113
def __attrs_post_init__(self):
90114
"""Prepare table info is it was not set and set up translation methods."""
91115
if self._table_info is None:

src/dynamodb_encryption_sdk/internal/crypto/authentication.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
from cryptography.hazmat.backends import default_backend
1515
from cryptography.hazmat.primitives import hashes
1616

17+
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
18+
from typing import Text # noqa pylint: disable=unused-import
19+
from dynamodb_encryption_sdk.internal import dynamodb_types # noqa pylint: disable=unused-import
20+
except ImportError: # pragma: no cover
21+
# We only actually need these imports when running the mypy checks
22+
pass
23+
1724
from dynamodb_encryption_sdk.delegated_keys import DelegatedKey # noqa pylint: disable=unused-import
1825
from dynamodb_encryption_sdk.encrypted import CryptoConfig # noqa pylint: disable=unused-import
1926
from dynamodb_encryption_sdk.identifiers import CryptoAction
@@ -71,7 +78,7 @@ def verify_item_signature(signature_attribute, encrypted_item, verification_key,
7178

7279

7380
def _string_to_sign(item, table_name, attribute_actions):
74-
# type: (dynamodb_type.ITEM, Text, AttributeActions) -> bytes
81+
# type: (dynamodb_types.ITEM, Text, AttributeActions) -> bytes
7582
"""Generate the string to sign from an encrypted item and configuration.
7683
7784
:param dict item: Encrypted DynamoDB item

src/dynamodb_encryption_sdk/internal/crypto/jce_bridge/authentication.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import six
2222

2323
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
24-
from typing import Text # noqa pylint: disable=unused-import
24+
from typing import Any, Callable, Text # noqa pylint: disable=unused-import
2525
except ImportError: # pragma: no cover
2626
# We only actually need these imports when running the mypy checks
2727
pass
@@ -87,7 +87,7 @@ def verify(self, key, signature, data):
8787
"""
8888

8989

90-
@attr.s
90+
@attr.s(init=False)
9191
class JavaMac(JavaAuthenticator):
9292
"""Symmetric MAC authenticators.
9393
@@ -99,6 +99,22 @@ class JavaMac(JavaAuthenticator):
9999
algorithm_type = attr.ib(validator=callable_validator)
100100
hash_type = attr.ib(validator=callable_validator)
101101

102+
def __init__(
103+
self,
104+
java_name, # type: Text
105+
algorithm_type, # type: Callable
106+
hash_type # type: Callable
107+
):
108+
# type: (...) -> None
109+
"""Workaround pending resolution of attrs/mypy interaction.
110+
https://github.com/python/mypy/issues/2088
111+
https://github.com/python-attrs/attrs/issues/215
112+
"""
113+
self.java_name = java_name
114+
self.algorithm_type = algorithm_type
115+
self.hash_type = hash_type
116+
attr.validate(self)
117+
102118
def _build_hmac_signer(self, key):
103119
# type: (bytes) -> Any
104120
"""Build HMAC signer using instance algorithm and hash type and ``key``.
@@ -182,7 +198,7 @@ def verify(self, key, signature, data):
182198
raise SignatureVerificationError(message)
183199

184200

185-
@attr.s
201+
@attr.s(init=False)
186202
class JavaSignature(JavaAuthenticator):
187203
"""Asymmetric signature authenticators.
188204
@@ -195,6 +211,24 @@ class JavaSignature(JavaAuthenticator):
195211
hash_type = attr.ib(validator=callable_validator)
196212
padding_type = attr.ib(validator=callable_validator)
197213

214+
def __init__(
215+
self,
216+
java_name, # type: Text
217+
algorithm_type,
218+
hash_type, # type: Callable
219+
padding_type # type: Callable
220+
):
221+
# type: (...) -> None
222+
"""Workaround pending resolution of attrs/mypy interaction.
223+
https://github.com/python/mypy/issues/2088
224+
https://github.com/python-attrs/attrs/issues/215
225+
"""
226+
self.java_name = java_name
227+
self.algorithm_type = algorithm_type
228+
self.hash_type = hash_type
229+
self.padding_type = padding_type
230+
attr.validate(self)
231+
198232
def validate_algorithm(self, algorithm):
199233
# type: (Text) -> None
200234
"""Determine whether the requested algorithm name is compatible with this authenticator.

0 commit comments

Comments
 (0)