diff --git a/CHANGELOG.md b/CHANGELOG.md index 34353e2..e166da1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.1.1] - 2019-08-14 + +### Changed + +- Bumped FS to 2.4 +- Bumped Boto to 1.9 + ## [1.1.0] - 2018-01-01 ### Changed diff --git a/fs_s3fs/_s3fs.py b/fs_s3fs/_s3fs.py index 83b6fb2..d7f98e2 100644 --- a/fs_s3fs/_s3fs.py +++ b/fs_s3fs/_s3fs.py @@ -13,7 +13,6 @@ import tempfile import threading import mimetypes -import json import boto3 from botocore.exceptions import ClientError, EndpointConnectionError diff --git a/fs_s3fs/_version.py b/fs_s3fs/_version.py index 6849410..a82b376 100644 --- a/fs_s3fs/_version.py +++ b/fs_s3fs/_version.py @@ -1 +1 @@ -__version__ = "1.1.0" +__version__ = "1.1.1" diff --git a/fs_s3fs/opener.py b/fs_s3fs/opener.py index 872596d..d839f83 100644 --- a/fs_s3fs/opener.py +++ b/fs_s3fs/opener.py @@ -1,11 +1,11 @@ # coding: utf-8 -"""Defines the S3FSpener.""" +"""Defines the S3FS Opener.""" from __future__ import absolute_import from __future__ import print_function from __future__ import unicode_literals -__all__ = ['S3FSOpener'] +__all__ = ["S3FSOpener"] from fs.opener import Opener from fs.opener.errors import OpenerError @@ -14,27 +14,25 @@ class S3FSOpener(Opener): - protocols = ['s3'] + protocols = ["s3"] def open_fs(self, fs_url, parse_result, writeable, create, cwd): - bucket_name, _, dir_path = parse_result.resource.partition('/') + bucket_name, _, dir_path = parse_result.resource.partition("/") if not bucket_name: - raise OpenerError( - "invalid bucket name in '{}'".format(fs_url) - ) + raise OpenerError("invalid bucket name in '{}'".format(fs_url)) strict = ( - parse_result.params['strict'] == '1' - if 'strict' in parse_result.params + parse_result.params["strict"] == "1" + if "strict" in parse_result.params else True ) s3fs = S3FS( bucket_name, - dir_path=dir_path or '/', + dir_path=dir_path or "/", aws_access_key_id=parse_result.username or None, aws_secret_access_key=parse_result.password or None, - endpoint_url=parse_result.params.get('endpoint_url', None), - acl=parse_result.params.get('acl', None), - cache_control=parse_result.params.get('cache_control', None), - strict=strict + endpoint_url=parse_result.params.get("endpoint_url", None), + acl=parse_result.params.get("acl", None), + cache_control=parse_result.params.get("cache_control", None), + strict=strict, ) return s3fs diff --git a/fs_s3fs/tests/test_s3fs.py b/fs_s3fs/tests/test_s3fs.py index 27c83e9..ae113ae 100644 --- a/fs_s3fs/tests/test_s3fs.py +++ b/fs_s3fs/tests/test_s3fs.py @@ -5,7 +5,6 @@ from nose.plugins.attrib import attr from fs.test import FSTestCases - from fs_s3fs import S3FS import boto3 @@ -13,69 +12,68 @@ class TestS3FS(FSTestCases, unittest.TestCase): """Test S3FS implementation from dir_path.""" - bucket_name = 'fsexample' - s3 = boto3.resource('s3') - client = boto3.client('s3') + + bucket_name = "fsexample" + s3 = boto3.resource("s3") + client = boto3.client("s3") def make_fs(self): self._delete_bucket_contents() return S3FS(self.bucket_name) def _delete_bucket_contents(self): - response = self.client.list_objects( - Bucket=self.bucket_name - ) + response = self.client.list_objects(Bucket=self.bucket_name) contents = response.get("Contents", ()) for obj in contents: - self.client.delete_object( - Bucket=self.bucket_name, - Key=obj["Key"] - ) + self.client.delete_object(Bucket=self.bucket_name, Key=obj["Key"]) -@attr('slow') +@attr("slow") class TestS3FSSubDir(FSTestCases, unittest.TestCase): """Test S3FS implementation from dir_path.""" - bucket_name = 'fsexample' - s3 = boto3.resource('s3') - client = boto3.client('s3') + + bucket_name = "fsexample" + s3 = boto3.resource("s3") + client = boto3.client("s3") def make_fs(self): self._delete_bucket_contents() - self.s3.Object(self.bucket_name, 'subdirectory').put() - return S3FS(self.bucket_name, dir_path='subdirectory') + self.s3.Object(self.bucket_name, "subdirectory").put() + return S3FS(self.bucket_name, dir_path="subdirectory") def _delete_bucket_contents(self): - response = self.client.list_objects( - Bucket=self.bucket_name - ) + response = self.client.list_objects(Bucket=self.bucket_name) contents = response.get("Contents", ()) for obj in contents: - self.client.delete_object( - Bucket=self.bucket_name, - Key=obj["Key"] - ) + self.client.delete_object(Bucket=self.bucket_name, Key=obj["Key"]) class TestS3FSHelpers(unittest.TestCase): - def test_path_to_key(self): - s3 = S3FS('foo') - self.assertEqual(s3._path_to_key('foo.bar'), 'foo.bar') - self.assertEqual(s3._path_to_key('foo/bar'), 'foo/bar') + s3 = S3FS("foo") + self.assertEqual(s3._path_to_key("foo.bar"), "foo.bar") + self.assertEqual(s3._path_to_key("foo/bar"), "foo/bar") def test_path_to_key_subdir(self): - s3 = S3FS('foo', '/dir') - self.assertEqual(s3._path_to_key('foo.bar'), 'dir/foo.bar') - self.assertEqual(s3._path_to_key('foo/bar'), 'dir/foo/bar') + s3 = S3FS("foo", "/dir") + self.assertEqual(s3._path_to_key("foo.bar"), "dir/foo.bar") + self.assertEqual(s3._path_to_key("foo/bar"), "dir/foo/bar") def test_upload_args(self): - s3 = S3FS('foo', acl='acl', cache_control='cc') - self.assertDictEqual(s3._get_upload_args('test.jpg'), - {'ACL': 'acl', 'CacheControl': 'cc', 'ContentType': 'image/jpeg'}) - self.assertDictEqual(s3._get_upload_args('test.mp3'), - {'ACL': 'acl', 'CacheControl': 'cc', 'ContentType': 'audio/mpeg'}) - self.assertDictEqual(s3._get_upload_args('test.json'), - {'ACL': 'acl', 'CacheControl': 'cc', 'ContentType': 'application/json'}) - self.assertDictEqual(s3._get_upload_args('unknown.unknown'), - {'ACL': 'acl', 'CacheControl': 'cc', 'ContentType': 'binary/octet-stream'}) + s3 = S3FS("foo", acl="acl", cache_control="cc") + self.assertDictEqual( + s3._get_upload_args("test.jpg"), + {"ACL": "acl", "CacheControl": "cc", "ContentType": "image/jpeg"}, + ) + self.assertDictEqual( + s3._get_upload_args("test.mp3"), + {"ACL": "acl", "CacheControl": "cc", "ContentType": "audio/mpeg"}, + ) + self.assertDictEqual( + s3._get_upload_args("test.json"), + {"ACL": "acl", "CacheControl": "cc", "ContentType": "application/json"}, + ) + self.assertDictEqual( + s3._get_upload_args("unknown.unknown"), + {"ACL": "acl", "CacheControl": "cc", "ContentType": "binary/octet-stream"}, + ) diff --git a/setup.py b/setup.py index f417e33..a9c0c92 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ with open("README.rst", "rt") as f: DESCRIPTION = f.read() -REQUIREMENTS = ["boto3~=1.7", "fs~=2.2", "six~=1.10"] +REQUIREMENTS = ["boto3~=1.9", "fs~=2.4", "six~=1.10"] setup( name="fs-s3fs", diff --git a/tox.ini b/tox.ini index d7509c4..8054f9a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,11 @@ [tox] -envlist = py27,py34,py35,py36,pypy +envlist = py27,py34,py35,py36,py37,pypy sitepackages = False [testenv] deps = nose - boto3==1.7.64 - fs==2.1.0 + boto3==1.9.207 + fs==2.4.10 passenv = * #changedir=.tox