Skip to content

Commit 9744382

Browse files
avinash1IBMGitHub Enterprise
authored and
GitHub Enterprise
committed
Release 2.13.1
1 parent 5962dbd commit 9744382

File tree

14 files changed

+136
-70
lines changed

14 files changed

+136
-70
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# CHANGELOG
22

3+
## 2.13.1
4+
5+
### Content
6+
7+
#### Defect Fixes
8+
9+
* IBM Python SDK aligned with AWS Python SDK - Boto3(v1.26.64), Botocore(v1.29.65) and S3transfer(v0.6.0)
10+
* Update dependencies
11+
312
## 2.13.0
413

514
### Content

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ You\'ll need:
2727
* Token acquisition endpoint.
2828
* Service endpoint.
2929

30-
These values can be found in the IBM Cloud Console by [generating a \'service credential\'](https://cloud.ibm.com/docs/services/cloud-object-storage/iam/service-credentials.html).
30+
These values can be found in the IBM Cloud Console by [generating a \'service credential\'](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials).
3131

3232
## Using Python
3333

ibm_boto3/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
__author__ = 'IBM'
22-
__version__ = '2.13.0'
22+
__version__ = '2.13.1'
2323

2424

2525
# The default Boto3 session; autoloaded when needed.

ibm_boto3/compat.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,15 @@
1616
import socket
1717
import warnings
1818

19-
from ibm_botocore.vendored import six
2019
from ibm_boto3.exceptions import PythonDeprecationWarning
2120

22-
if six.PY3:
23-
# In python3, socket.error is OSError, which is too general
24-
# for what we want (i.e FileNotFoundError is a subclass of OSError).
25-
# In py3 all the socket related errors are in a newly created
26-
# ConnectionError
27-
SOCKET_ERROR = ConnectionError
28-
else:
29-
SOCKET_ERROR = socket.error
21+
# In python3, socket.error is OSError, which is too general
22+
# for what we want (i.e FileNotFoundError is a subclass of OSError).
23+
# In py3 all the socket related errors are in a newly created
24+
# ConnectionError
25+
SOCKET_ERROR = ConnectionError
3026

31-
if six.PY3:
32-
import collections.abc as collections_abc
33-
else:
34-
import collections as collections_abc
27+
import collections.abc as collections_abc
3528

3629

3730
if sys.platform.startswith('win'):
@@ -64,18 +57,17 @@ def filter_python_deprecation_warnings():
6457

6558

6659
def _warn_deprecated_python():
67-
"""Python 2.7 is deprecated so this code will no longer run.
68-
69-
Use this template for future deprecation campaigns as needed.
70-
"""
71-
py_27_params = {
72-
'date': 'July 15, 2021',
73-
'blog_link': 'https://aws.amazon.com/blogs/developer/announcing-end-'
74-
'of-support-for-python-2-7-in-aws-sdk-for-python-and-'
75-
'aws-cli-v1/'
60+
"""Use this template for future deprecation campaigns as needed."""
61+
py_36_params = {
62+
'date': 'May 30, 2022',
63+
'blog_link': (
64+
'https://aws.amazon.com/blogs/developer/'
65+
'python-support-policy-updates-for-aws-sdks-and-tools/'
66+
)
7667
}
7768
deprecated_versions = {
78-
(2,7): py_27_params,
69+
# Example template for future deprecations
70+
# (3, 6): py_36_params,
7971
}
8072
py_version = sys.version_info[:2]
8173

@@ -84,7 +76,7 @@ def _warn_deprecated_python():
8476
warning = (
8577
"Boto3 will no longer support Python {}.{} "
8678
"starting {}. To continue receiving service updates, "
87-
"bug fixes, and security updates please upgrade to Python 3.6 or "
79+
"bug fixes, and security updates please upgrade to Python 3.7 or "
8880
"later. More information can be found here: {}"
8981
).format(py_version[0], py_version[1], params['date'], params['blog_link'])
9082
warnings.warn(warning, PythonDeprecationWarning)

ibm_boto3/s3/transfer.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ def __call__(self, bytes_amount):
122122
123123
124124
"""
125+
from os import PathLike, fspath
126+
125127
from ibm_botocore.exceptions import ClientError
126128
from ibm_s3transfer.exceptions import (
127129
RetriesExceededError as S3TransferRetriesExceededError,
@@ -210,7 +212,7 @@ def __init__(
210212
211213
:param use_threads: If True, threads will be used when performing
212214
S3 transfers. If False, no threads will be used in
213-
performing transfers: all logic will be ran in the main thread.
215+
performing transfers; all logic will be run in the main thread.
214216
215217
:param max_bandwidth: The maximum bandwidth that will be consumed
216218
in uploading and downloading file content. The value is an integer
@@ -277,8 +279,10 @@ def upload_file(
277279
:py:meth:`S3.Client.upload_file`
278280
:py:meth:`S3.Client.upload_fileobj`
279281
"""
282+
if isinstance(filename, PathLike):
283+
filename = fspath(filename)
280284
if not isinstance(filename, str):
281-
raise ValueError('Filename must be a string')
285+
raise ValueError('Filename must be a string or a path-like object')
282286

283287
subscribers = self._get_subscribers(callback)
284288
future = self._manager.upload(
@@ -309,8 +313,10 @@ def download_file(
309313
:py:meth:`S3.Client.download_file`
310314
:py:meth:`S3.Client.download_fileobj`
311315
"""
316+
if isinstance(filename, PathLike):
317+
filename = fspath(filename)
312318
if not isinstance(filename, str):
313-
raise ValueError('Filename must be a string')
319+
raise ValueError('Filename must be a string or a path-like object')
314320

315321
subscribers = self._get_subscribers(callback)
316322
future = self._manager.download(

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ wheel==0.40.0
22
coverage==5.5
33

44
# Pytest specific deps
5-
pytest==7.2.2
5+
pytest==7.3.1
66
pytest-cov==2.12.1
77
atomicwrites>=1.0 # Windows requirement
88
colorama>0.3.0 # Windows requirement

requirements-docs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
# removed python 3.5 support we need to add our own pins.
44
markupsafe>=1.1,<2.0
55
jinja2>=2.3,<3.0
6-
docutils>=0.10,<0.15
6+
docutils>=0.10,<0.17
77
Sphinx>=1.1.3,<=1.6.7
88
guzzle_sphinx_theme>=0.7.10,<0.8

setup.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ universal = 0
33

44
[metadata]
55
requires_dist =
6-
ibm-cos-sdk-core==2.13.0
7-
ibm-cos-sdk-s3transfer==2.13.0
8-
jmespath>=0.7.1,<=1.0.1
6+
ibm-cos-sdk-core==2.13.1
7+
ibm-cos-sdk-s3transfer==2.13.1
8+
jmespath>=0.10.0,<=1.0.1
99

1010
[flake8]
1111
ignore = E203,E501,W503,W504

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010

1111
requires = [
12-
'ibm-cos-sdk-core==2.13.0',
13-
'ibm-cos-sdk-s3transfer==2.13.0',
12+
'ibm-cos-sdk-core==2.13.1',
13+
'ibm-cos-sdk-s3transfer==2.13.1',
1414
'jmespath>=0.10.0,<=1.0.1'
1515
]
1616

tests/functional/test_s3.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13+
import io
14+
1315
import ibm_botocore
1416
import ibm_botocore.stub
1517
import pytest
16-
from ibm_botocore.compat import six
1718
from ibm_botocore.config import Config
1819
from ibm_botocore.stub import Stubber
1920

@@ -244,7 +245,7 @@ def progress_callback(amount):
244245
class TestUploadFileobj(BaseTransferTest):
245246
def setUp(self):
246247
super().setUp()
247-
self.contents = six.BytesIO(b'foo\n')
248+
self.contents = io.BytesIO(b'foo\n')
248249

249250
def stub_put_object(self):
250251
put_object_response = {
@@ -330,7 +331,7 @@ def test_object_upload(self):
330331

331332
def test_multipart_upload(self):
332333
chunksize = 8 * (1024**2)
333-
contents = six.BytesIO(b'0' * (chunksize * 3))
334+
contents = io.BytesIO(b'0' * (chunksize * 3))
334335
self.stub_multipart_upload(num_parts=3)
335336
transfer_config = TransferConfig(
336337
multipart_chunksize=chunksize,
@@ -354,7 +355,7 @@ class TestDownloadFileobj(BaseTransferTest):
354355
def setUp(self):
355356
super().setUp()
356357
self.contents = b'foo'
357-
self.fileobj = six.BytesIO()
358+
self.fileobj = io.BytesIO()
358359

359360
def stub_single_part_download(self):
360361
self.stub_head(content_length=len(self.contents))
@@ -400,7 +401,7 @@ def stub_get_object(self, full_contents, start_byte=0, end_byte=None):
400401
"ETag": self.etag,
401402
"ContentLength": len(contents),
402403
"ContentType": "binary/octet-stream",
403-
"Body": six.BytesIO(contents),
404+
"Body": io.BytesIO(contents),
404405
"ResponseMetadata": {"HTTPStatusCode": 200},
405406
}
406407
)

tests/integration/test_s3.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,22 @@
1212
# language governing permissions and limitations under the License.
1313
import datetime
1414
import hashlib
15+
import io
1516
import logging
1617
import math
1718
import os
1819
import shutil
1920
import string
2021
import tempfile
2122
import threading
23+
from pathlib import Path
2224

2325
from ibm_botocore.client import Config
24-
from ibm_botocore.compat import six
2526

2627
import ibm_boto3.s3.transfer
2728
import ibm_boto3.session
2829
from tests import unique_id, unittest
2930

30-
urlopen = six.moves.urllib.request.urlopen
3131
LOG = logging.getLogger('ibm_boto3.tests.integration')
3232

3333

@@ -338,7 +338,7 @@ def test_copy(self):
338338
self.object_exists('bar')
339339

340340
def test_upload_fileobj(self):
341-
fileobj = six.BytesIO(b'foo')
341+
fileobj = io.BytesIO(b'foo')
342342
self.client.upload_fileobj(
343343
Fileobj=fileobj, Bucket=self.bucket_name, Key='foo'
344344
)
@@ -356,7 +356,7 @@ def test_upload_fileobj_progress(self):
356356
multipart_threshold=chunksize,
357357
max_concurrency=1,
358358
)
359-
fileobj = six.BytesIO(b'0' * (chunksize * 3))
359+
fileobj = io.BytesIO(b'0' * (chunksize * 3))
360360

361361
def progress_callback(amount):
362362
self.progress += amount
@@ -374,7 +374,7 @@ def progress_callback(amount):
374374
self.assertEqual(self.progress, chunksize * 3)
375375

376376
def test_download_fileobj(self):
377-
fileobj = six.BytesIO()
377+
fileobj = io.BytesIO()
378378
self.client.put_object(
379379
Bucket=self.bucket_name, Key='foo', Body=b'beach'
380380
)
@@ -387,6 +387,13 @@ def test_download_fileobj(self):
387387

388388
self.assertEqual(fileobj.getvalue(), b'beach')
389389

390+
def test_upload_via_path(self):
391+
transfer = self.create_s3_transfer()
392+
filename = self.files.create_file_with_size('path.txt', filesize=1024)
393+
transfer.upload_file(Path(filename), self.bucket_name, 'path.txt')
394+
self.addCleanup(self.delete_object, 'path.txt')
395+
self.assertTrue(self.object_exists('path.txt'))
396+
390397
def test_upload_below_threshold(self):
391398
config = ibm_boto3.s3.transfer.TransferConfig(
392399
multipart_threshold=2 * 1024 * 1024
@@ -397,7 +404,6 @@ def test_upload_below_threshold(self):
397404
)
398405
transfer.upload_file(filename, self.bucket_name, 'foo.txt')
399406
self.addCleanup(self.delete_object, 'foo.txt')
400-
401407
self.assertTrue(self.object_exists('foo.txt'))
402408

403409
def test_upload_above_threshold(self):
@@ -692,7 +698,7 @@ def test_transfer_methods_do_not_use_threads(self):
692698
self.addCleanup(self.delete_object, key)
693699
self.assertTrue(self.object_exists(key))
694700

695-
fileobj = six.BytesIO()
701+
fileobj = io.BytesIO()
696702
self.client.download_fileobj(
697703
Bucket=self.bucket_name, Key='foo', Fileobj=fileobj, Config=config
698704
)

0 commit comments

Comments
 (0)