diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ab40d21d7..176df025b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,3 +4,7 @@ By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + +# Check any applicable: +- [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files. + diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 80b7fc304..d9bca1f73 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,23 @@ Changelog ********* +1.4.1 -- 2019-09-20 +=================== + +Bugfixes +-------- + +* Fix region configuration override in botocore sessions. + `#190 `_ + `#193 `_ + +Minor +----- + +* Caching CMM must require that max age configuration value is greater than 0. + `#147 `_ + `#172 `_ + 1.4.0 -- 2019-05-23 =================== diff --git a/decrypt_oracle/setup.py b/decrypt_oracle/setup.py index e5d9ec84f..e8dfb2aac 100644 --- a/decrypt_oracle/setup.py +++ b/decrypt_oracle/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Read the requirements file.""" requirements = read("requirements-actual.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 23a9ece86..f0a7804e5 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -156,7 +156,7 @@ basepython = python3 deps = flake8 flake8-docstrings - pydocstyle < 4.0.0 + pydocstyle<4.0.0 # https://github.com/JBKahn/flake8-print/pull/30 flake8-print>=3.1.0 commands = diff --git a/doc/requirements.txt b/doc/requirements.txt index 29e319455..9a54370d6 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,2 +1,2 @@ sphinx>=1.3.0 -sphinx_rtd_theme \ No newline at end of file +sphinx_rtd_theme diff --git a/examples/src/one_kms_cmk_unsigned.py b/examples/src/one_kms_cmk_unsigned.py new file mode 100644 index 000000000..df2f4373d --- /dev/null +++ b/examples/src/one_kms_cmk_unsigned.py @@ -0,0 +1,51 @@ +# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +"""Example showing basic encryption and decryption of a value already in memory +using one KMS CMK with an unsigned algorithm. +""" +from aws_encryption_sdk import KMSMasterKeyProvider, decrypt, encrypt +from aws_encryption_sdk.identifiers import Algorithm + + +def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): + """Encrypts and then decrypts a string under one KMS customer master key (CMK) with an unsigned algorithm. + + :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK + :param bytes source_plaintext: Data to encrypt + :param botocore_session: existing botocore session instance + :type botocore_session: botocore.session.Session + """ + kwargs = dict(key_ids=[key_arn]) + + if botocore_session is not None: + kwargs["botocore_session"] = botocore_session + + # Create master key provider using the ARN of the key and the session (botocore_session) + kms_key_provider = KMSMasterKeyProvider(**kwargs) + + # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header + ciphertext, encrypted_message_header = encrypt( + algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256, source=source_plaintext, key_provider=kms_key_provider + ) + + # Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header + plaintext, decrypted_message_header = decrypt(source=ciphertext, key_provider=kms_key_provider) + + # Check if the original message and the decrypted message are the same + assert source_plaintext == plaintext + + # Check if the headers of the encrypted message and decrypted message match + assert all( + pair in encrypted_message_header.encryption_context.items() + for pair in decrypted_message_header.encryption_context.items() + ) diff --git a/examples/test/test_i_one_kms_cmk_unsigned.py b/examples/test/test_i_one_kms_cmk_unsigned.py new file mode 100644 index 000000000..8a2758c96 --- /dev/null +++ b/examples/test/test_i_one_kms_cmk_unsigned.py @@ -0,0 +1,29 @@ +# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +"""Unit test suite for the encryption and decryption using one KMS CMK with an unsigned algorithm example.""" + +import botocore.session +import pytest + +from ..src.one_kms_cmk_unsigned import encrypt_decrypt +from .examples_test_utils import get_cmk_arn +from .examples_test_utils import static_plaintext + + +pytestmark = [pytest.mark.examples] + + +def test_one_kms_cmk_unsigned(): + plaintext = static_plaintext + cmk_arn = get_cmk_arn() + encrypt_decrypt(key_arn=cmk_arn, source_plaintext=plaintext, botocore_session=botocore.session.Session()) diff --git a/requirements.txt b/requirements.txt index 8378d126e..08e1d1a72 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ six boto3>=1.4.4 cryptography>=1.8.1 attrs>=19.1.0 -wrapt>=1.10.11 \ No newline at end of file +wrapt>=1.10.11 diff --git a/setup.py b/setup.py index 1afa9d869..6ceb2d8fb 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Reads the requirements file.""" requirements = read("requirements.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/src/aws_encryption_sdk/caches/__init__.py b/src/aws_encryption_sdk/caches/__init__.py index 3d3189441..9d2afa485 100644 --- a/src/aws_encryption_sdk/caches/__init__.py +++ b/src/aws_encryption_sdk/caches/__init__.py @@ -143,6 +143,7 @@ class CryptoMaterialsCacheEntryHints(object): @attr.s(hash=False) class CryptoMaterialsCacheEntry(object): + # pylint: disable=too-many-instance-attributes """Value and metadata store for cryptographic materials cache entries. :param bytes cache_key: Identifier for entries in cache diff --git a/src/aws_encryption_sdk/identifiers.py b/src/aws_encryption_sdk/identifiers.py index 7f5cd3f1f..87d5919a1 100644 --- a/src/aws_encryption_sdk/identifiers.py +++ b/src/aws_encryption_sdk/identifiers.py @@ -27,7 +27,7 @@ # We only actually need these imports when running the mypy checks pass -__version__ = "1.4.0" +__version__ = "1.4.1" USER_AGENT_SUFFIX = "AwsEncryptionSdkPython/{}".format(__version__) diff --git a/src/aws_encryption_sdk/key_providers/kms.py b/src/aws_encryption_sdk/key_providers/kms.py index df089e3b1..c0a2dc46e 100644 --- a/src/aws_encryption_sdk/key_providers/kms.py +++ b/src/aws_encryption_sdk/key_providers/kms.py @@ -161,8 +161,8 @@ def add_regional_client(self, region_name): :param str region_name: AWS Region ID (ex: us-east-1) """ if region_name not in self._regional_clients: - session = boto3.session.Session(region_name=region_name, botocore_session=self.config.botocore_session) - client = session.client("kms", config=self._user_agent_adding_config) + session = boto3.session.Session(botocore_session=self.config.botocore_session) + client = session.client("kms", region_name=region_name, config=self._user_agent_adding_config) self._register_client(client, region_name) self._regional_clients[region_name] = client diff --git a/src/aws_encryption_sdk/keyring/base.py b/src/aws_encryption_sdk/keyring/base.py index 770b53c0b..236037b4e 100644 --- a/src/aws_encryption_sdk/keyring/base.py +++ b/src/aws_encryption_sdk/keyring/base.py @@ -11,8 +11,13 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. """Base class interface for Keyrings.""" -from aws_encryption_sdk.materials_managers import DecryptionMaterials, EncryptionMaterials -from aws_encryption_sdk.structures import EncryptedDataKey +from aws_encryption_sdk.materials_managers import ( # only used for mypy; pylint: disable=unused-import,duplicate-code + DecryptionMaterials, + EncryptionMaterials, +) +from aws_encryption_sdk.structures import ( # only used for mypy; pylint: disable=unused-import,duplicate-code + EncryptedDataKey, +) try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/src/aws_encryption_sdk/keyring/multi_keyring.py b/src/aws_encryption_sdk/keyring/multi_keyring.py index f43820be5..cb2b5cc79 100644 --- a/src/aws_encryption_sdk/keyring/multi_keyring.py +++ b/src/aws_encryption_sdk/keyring/multi_keyring.py @@ -17,7 +17,10 @@ from attr.validators import deep_iterable, instance_of, optional from aws_encryption_sdk.exceptions import EncryptKeyError, GenerateKeyError -from aws_encryption_sdk.keyring.base import DecryptionMaterials, EncryptedDataKey, EncryptionMaterials, Keyring +from aws_encryption_sdk.keyring.base import DecryptionMaterials # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.keyring.base import EncryptionMaterials # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.keyring.base import Keyring +from aws_encryption_sdk.structures import EncryptedDataKey # only used for mypy so pylint: disable=unused-import try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/src/aws_encryption_sdk/keyring/raw_keyring.py b/src/aws_encryption_sdk/keyring/raw_keyring.py index 513119246..922f6ae0c 100644 --- a/src/aws_encryption_sdk/keyring/raw_keyring.py +++ b/src/aws_encryption_sdk/keyring/raw_keyring.py @@ -29,8 +29,12 @@ from aws_encryption_sdk.internal.formatting.serialize import serialize_raw_master_key_prefix, serialize_wrapped_key from aws_encryption_sdk.key_providers.raw import RawMasterKey from aws_encryption_sdk.keyring.base import Keyring -from aws_encryption_sdk.materials_managers import DecryptionMaterials, EncryptionMaterials -from aws_encryption_sdk.structures import EncryptedDataKey, KeyringTrace, MasterKeyInfo, RawDataKey +from aws_encryption_sdk.materials_managers import ( # only used for mypy so pylint: disable=unused-import + DecryptionMaterials, + EncryptionMaterials, +) +from aws_encryption_sdk.structures import EncryptedDataKey # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.structures import KeyringTrace, MasterKeyInfo, RawDataKey try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/src/aws_encryption_sdk/materials_managers/caching.py b/src/aws_encryption_sdk/materials_managers/caching.py index b2bdcba9f..992a39a7a 100644 --- a/src/aws_encryption_sdk/materials_managers/caching.py +++ b/src/aws_encryption_sdk/materials_managers/caching.py @@ -108,6 +108,9 @@ def __attrs_post_init__(self): if self.max_bytes_encrypted > MAX_BYTES_PER_KEY: raise ValueError("max_bytes_encrypted cannot exceed {}".format(MAX_BYTES_PER_KEY)) + if self.max_age <= 0.0: + raise ValueError("max_age cannot be less than or equal to 0") + if self.backing_materials_manager is None: if self.master_key_provider is None: raise TypeError("Either backing_materials_manager or master_key_provider must be defined") diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 90dc9d25c..504f68977 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -235,7 +235,7 @@ def read(self, b=-1): if not self._message_prepped: self._prep_message() - if self.closed: + if self.closed: # dynamic values confuse pylint: disable=using-constant-test raise ValueError("I/O operation on closed file") if b >= 0: @@ -283,7 +283,7 @@ def readline(self): def readlines(self): """Reads all chunks of output, outputting a list as defined in the IOBase specification.""" - return [line for line in self] + return list(self) def __iter__(self): """Make this class and subclasses identify as iterators.""" @@ -292,7 +292,7 @@ def __iter__(self): def next(self): """Provides hook for Python2 iterator functionality.""" _LOGGER.debug("reading next") - if self.closed: + if self.closed: # dynamic values confuse pylint: disable=using-constant-test _LOGGER.debug("stream is closed") raise StopIteration() diff --git a/src/aws_encryption_sdk/structures.py b/src/aws_encryption_sdk/structures.py index 635f661ce..ea9253b39 100644 --- a/src/aws_encryption_sdk/structures.py +++ b/src/aws_encryption_sdk/structures.py @@ -117,6 +117,7 @@ class KeyringTrace(object): @attr.s(hash=True) class MessageHeader(object): + # pylint: disable=too-many-instance-attributes """Deserialized message header object. :param version: Message format version, per spec diff --git a/test/integration/integration_test_utils.py b/test/integration/integration_test_utils.py index a5b4d6001..b65d93570 100644 --- a/test/integration/integration_test_utils.py +++ b/test/integration/integration_test_utils.py @@ -13,10 +13,13 @@ """Utility functions to handle configuration and credentials setup for integration tests.""" import os +import botocore.session + from aws_encryption_sdk.key_providers.kms import KMSMasterKeyProvider AWS_KMS_KEY_ID = "AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID" _KMS_MKP = None +_KMS_MKP_BOTO = None def get_cmk_arn(): @@ -47,3 +50,19 @@ def setup_kms_master_key_provider(cache=True): _KMS_MKP = kms_master_key_provider return kms_master_key_provider + + +def setup_kms_master_key_provider_with_botocore_session(cache=True): + """Reads the test_values config file and builds the requested KMS Master Key Provider with botocore_session.""" + global _KMS_MKP_BOTO # pylint: disable=global-statement + if cache and _KMS_MKP_BOTO is not None: + return _KMS_MKP_BOTO + + cmk_arn = get_cmk_arn() + kms_master_key_provider = KMSMasterKeyProvider(botocore_session=botocore.session.Session()) + kms_master_key_provider.add_master_key(cmk_arn) + + if cache: + _KMS_MKP_BOTO = kms_master_key_provider + + return kms_master_key_provider diff --git a/test/integration/test_i_aws_encrytion_sdk_client.py b/test/integration/test_i_aws_encrytion_sdk_client.py index 56b0536fd..26df431dc 100644 --- a/test/integration/test_i_aws_encrytion_sdk_client.py +++ b/test/integration/test_i_aws_encrytion_sdk_client.py @@ -21,7 +21,11 @@ from aws_encryption_sdk.identifiers import USER_AGENT_SUFFIX, Algorithm from aws_encryption_sdk.key_providers.kms import KMSMasterKey, KMSMasterKeyProvider -from .integration_test_utils import get_cmk_arn, setup_kms_master_key_provider +from .integration_test_utils import ( + get_cmk_arn, + setup_kms_master_key_provider, + setup_kms_master_key_provider_with_botocore_session, +) pytestmark = [pytest.mark.integ] @@ -68,6 +72,15 @@ def test_remove_bad_client(): assert not test._regional_clients +def test_regional_client_does_not_modify_botocore_session(caplog): + mkp = setup_kms_master_key_provider_with_botocore_session() + fake_region = "us-fakey-12" + + assert mkp.config.botocore_session.get_config_variable("region") != fake_region + mkp.add_regional_client(fake_region) + assert mkp.config.botocore_session.get_config_variable("region") != fake_region + + class TestKMSThickClientIntegration(object): @pytest.fixture(autouse=True) def apply_fixtures(self): diff --git a/test/requirements.txt b/test/requirements.txt index d1b878ce2..152b5dbf4 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,4 +1,4 @@ mock pytest>=3.3.1 pytest-cov -pytest-mock \ No newline at end of file +pytest-mock diff --git a/test/unit/test_identifiers.py b/test/unit/test_identifiers.py index 8f13b1314..3fd421b65 100644 --- a/test/unit/test_identifiers.py +++ b/test/unit/test_identifiers.py @@ -41,7 +41,7 @@ def test_algorithm_safe_to_cache(check_algorithm, safe_to_cache): assert not check_algorithm.safe_to_cache() -@pytest.mark.parametrize("suite", [suite for suite in EncryptionSuite]) +@pytest.mark.parametrize("suite", list(EncryptionSuite)) def test_encryption_suite_invalid_kdf(suite): mock_kdf = Mock() mock_kdf.input_length.return_value = 1 diff --git a/test/unit/test_material_managers_caching.py b/test/unit/test_material_managers_caching.py index 426fe3348..833d6aa53 100644 --- a/test/unit/test_material_managers_caching.py +++ b/test/unit/test_material_managers_caching.py @@ -117,6 +117,8 @@ def test_mkp_to_default_cmm(mocker): dict(max_bytes_encrypted=MAX_BYTES_PER_KEY + 1), r"max_bytes_encrypted cannot exceed {}".format(MAX_BYTES_PER_KEY), ), + (dict(max_age=0.0), r"max_age cannot be less than or equal to 0"), + (dict(max_age=-1.0), r"max_age cannot be less than or equal to 0"), ), ) def test_invalid_values(invalid_kwargs, error_message): diff --git a/test/unit/test_providers_kms_master_key_provider.py b/test/unit/test_providers_kms_master_key_provider.py index 48802a36f..f8d8dc453 100644 --- a/test/unit/test_providers_kms_master_key_provider.py +++ b/test/unit/test_providers_kms_master_key_provider.py @@ -12,6 +12,7 @@ # language governing permissions and limitations under the License. """Unit test suite from aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider""" import botocore.client +import botocore.session import pytest from mock import ANY, MagicMock, call, patch, sentinel @@ -22,6 +23,19 @@ pytestmark = [pytest.mark.unit, pytest.mark.local] +@pytest.fixture(autouse=True, params=[True, False], ids=["default region", "no default region"]) +def patch_default_region(request, monkeypatch): + """Run all tests in this module both with a default region set and no default region set. + + This ensures that we do not regress on default region handling. + https://github.com/aws/aws-encryption-sdk-python/issues/31 + """ + if request.param: + monkeypatch.setenv("AWS_DEFAULT_REGION", "us-west-2") + else: + monkeypatch.delenv("AWS_DEFAULT_REGION", raising=False) + + def test_init_with_regionless_key_ids_and_region_names(): key_ids = ("alias/key_1",) region_names = ("test-region-1",) @@ -32,6 +46,7 @@ def test_init_with_regionless_key_ids_and_region_names(): class TestKMSMasterKeyProvider(object): @pytest.fixture(autouse=True) def apply_fixtures(self): + self.botocore_no_region_session = botocore.session.Session(session_vars={"region": (None, None, None, None)}) self.mock_botocore_session_patcher = patch("aws_encryption_sdk.key_providers.kms.botocore.session.Session") self.mock_botocore_session = self.mock_botocore_session_patcher.start() self.mock_boto3_session_patcher = patch("aws_encryption_sdk.key_providers.kms.boto3.session.Session") @@ -69,7 +84,7 @@ def test_init_with_region_names(self, mock_add_clients): @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") def test_init_with_default_region_found(self, mock_add_regional_client): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) assert test.default_region is None with patch.object( test.config.botocore_session, "get_config_variable", return_value=sentinel.default_region @@ -77,11 +92,11 @@ def test_init_with_default_region_found(self, mock_add_regional_client): test._process_config() mock_get_config.assert_called_once_with("region") assert test.default_region is sentinel.default_region - mock_add_regional_client.assert_called_once_with(sentinel.default_region) + mock_add_regional_client.assert_called_with(sentinel.default_region) @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") def test_init_with_default_region_not_found(self, mock_add_regional_client): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) assert test.default_region is None with patch.object(test.config.botocore_session, "get_config_variable", return_value=None) as mock_get_config: test._process_config() @@ -93,12 +108,14 @@ def test_add_regional_client_new(self): test = KMSMasterKeyProvider() test._regional_clients = {} test.add_regional_client("ex_region_name") - self.mock_boto3_session.assert_called_once_with(region_name="ex_region_name", botocore_session=ANY) - self.mock_boto3_session_instance.client.assert_called_once_with("kms", config=test._user_agent_adding_config) + self.mock_boto3_session.assert_called_with(botocore_session=ANY) + self.mock_boto3_session_instance.client.assert_called_with( + "kms", region_name="ex_region_name", config=test._user_agent_adding_config + ) assert test._regional_clients["ex_region_name"] is self.mock_boto3_client_instance def test_add_regional_client_exists(self): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) test._regional_clients["ex_region_name"] = sentinel.existing_client test.add_regional_client("ex_region_name") assert not self.mock_boto3_session.called @@ -114,7 +131,7 @@ def test_client_valid_region_name(self, mock_add_client): test = KMSMasterKeyProvider() test._regional_clients["us-east-1"] = self.mock_boto3_client_instance client = test._client("arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb") - mock_add_client.assert_called_once_with("us-east-1") + mock_add_client.assert_called_with("us-east-1") assert client is self.mock_boto3_client_instance @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") @@ -124,10 +141,10 @@ def test_client_no_region_name_with_default(self, mock_add_client): test._regional_clients[sentinel.default_region] = sentinel.default_client client = test._client("") assert client is sentinel.default_client - mock_add_client.assert_called_once_with(sentinel.default_region) + mock_add_client.assert_called_with(sentinel.default_region) def test_client_no_region_name_without_default(self): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) with pytest.raises(UnknownRegionError) as excinfo: test._client("") excinfo.match("No default region found and no region determinable from key id: *") diff --git a/test_vector_handlers/compatibility-requirements/1.3.3 b/test_vector_handlers/compatibility-requirements/1.3.3 new file mode 100644 index 000000000..7aa43f6be --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/1.3.3 @@ -0,0 +1,2 @@ +aws-encryption-sdk==1.3.3 +attrs<19.2.0 diff --git a/test_vector_handlers/compatibility-requirements/1.3.max b/test_vector_handlers/compatibility-requirements/1.3.max new file mode 100644 index 000000000..72c946bf5 --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/1.3.max @@ -0,0 +1 @@ +aws-encryption-sdk >= 1.3.3, < 1.4.0 diff --git a/test_vector_handlers/compatibility-requirements/latest b/test_vector_handlers/compatibility-requirements/latest new file mode 100644 index 000000000..d0197da7f --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/latest @@ -0,0 +1 @@ +aws-encryption-sdk diff --git a/test_vector_handlers/requirements.txt b/test_vector_handlers/requirements.txt index 21e4de2f0..9de0ee532 100644 --- a/test_vector_handlers/requirements.txt +++ b/test_vector_handlers/requirements.txt @@ -1,3 +1,3 @@ attrs >= 17.4.0 aws-encryption-sdk -six \ No newline at end of file +six diff --git a/test_vector_handlers/setup.py b/test_vector_handlers/setup.py index f191b3869..bd16c76c8 100644 --- a/test_vector_handlers/setup.py +++ b/test_vector_handlers/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Read the requirements file.""" requirements = read("requirements.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/test_vector_handlers/test/requirements.txt b/test_vector_handlers/test/requirements.txt index d1b878ce2..152b5dbf4 100644 --- a/test_vector_handlers/test/requirements.txt +++ b/test_vector_handlers/test/requirements.txt @@ -1,4 +1,4 @@ mock pytest>=3.3.1 pytest-cov -pytest-mock \ No newline at end of file +pytest-mock diff --git a/test_vector_handlers/tox.ini b/test_vector_handlers/tox.ini index 748ba4881..fc2c8d5a7 100644 --- a/test_vector_handlers/tox.ini +++ b/test_vector_handlers/tox.ini @@ -46,9 +46,9 @@ passenv = sitepackages = False deps = -rtest/requirements.txt - awses_1.3.3: aws-encryption-sdk==1.3.3 - awses_1.3.max: aws-encryption-sdk >= 1.3.3, < 1.4.0 - awses_latest: aws-encryption-sdk + awses_1.3.3: -rcompatibility-requirements/1.3.3 + awses_1.3.max: -rcompatibility-requirements/1.3.max + awses_latest: -rcompatibility-requirements/latest commands = {[testenv:base-command]commands} [testenv:full-encrypt] diff --git a/tox.ini b/tox.ini index 3e5677ece..06564ef6a 100644 --- a/tox.ini +++ b/tox.ini @@ -117,7 +117,7 @@ basepython = python3 deps = flake8 flake8-docstrings - pydocstyle < 4.0.0 + pydocstyle<4.0.0 # https://github.com/JBKahn/flake8-print/pull/30 flake8-print>=3.1.0 flake8-bugbear