Skip to content

Commit 5f02655

Browse files
authored
Remove support for python 2 (#164)
Python 2.7 was end of life Jan 1, 2020. Remove all the hoops we were jumping through to support it. This fixes some bugs involving unicode strings. Also stop releasing wheel for Python 3.4 which was end of life in 2019.
1 parent 297d89b commit 5f02655

33 files changed

+177
-284
lines changed

.builder/actions/manylinux-ci.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
'cp35-cp35m',
99
'cp36-cp36m',
1010
'cp37-cp37m',
11-
'cp27-cp27m',
12-
'cp27-cp27mu',
1311
)
1412

1513

.lgtm.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extraction:
2+
cpp:
3+
index:
4+
# not sure why cpp builds are using python 2, but this should stop it
5+
build_command: "python3 setup.py build"

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
## AWS CRT Python
22

3-
Python bindings for the AWS Common Runtime.
3+
Python 3 bindings for the AWS Common Runtime.
44

55
API documentation: https://awslabs.github.io/aws-crt-python/
66

77
## License
88

99
This library is licensed under the Apache 2.0 License.
1010

11+
## Minimum Requirements:
12+
* Python 3.5+
13+
1114
## Installation
1215

1316
To install from pip:
1417
````bash
15-
python -m pip install awscrt
18+
python3 -m pip install awscrt
1619
````
1720

1821
To install from Github:
1922
````bash
2023
git clone https://github.com/awslabs/aws-crt-python.git
2124
cd aws-crt-python
2225
git submodule update --init
23-
python -m pip install .
26+
python3 -m pip install .
2427
````
2528

2629
To use from your Python application, declare `awscrt` as a dependency in your `setup.py` file.

awscrt/__init__.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0.
33

4-
from sys import version_info
54
from weakref import WeakSet
65

76
__all__ = [
@@ -13,7 +12,7 @@
1312
]
1413

1514

16-
class NativeResource(object):
15+
class NativeResource:
1716
"""
1817
Base for classes that bind to a native type.
1918
_binding is a python capsule referencing the native object.
@@ -33,12 +32,3 @@ class NativeResource(object):
3332
def __init__(self):
3433
if NativeResource._track_lifetime:
3534
NativeResource._living.add(self)
36-
37-
38-
def isinstance_str(x):
39-
"""
40-
Python 2/3 compatible way to check isinstance(x, str).
41-
"""
42-
if version_info[0] == 2:
43-
return isinstance(x, basestring)
44-
return isinstance(x, str)

awscrt/auth.py

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,13 @@
77

88
from __future__ import absolute_import
99
import _awscrt
10-
from awscrt import isinstance_str, NativeResource
10+
from awscrt import NativeResource
1111
import awscrt.exceptions
1212
from awscrt.http import HttpRequest
1313
from awscrt.io import ClientBootstrap
1414
from concurrent.futures import Future
1515
import datetime
1616
from enum import IntEnum
17-
import time
18-
19-
try:
20-
_utc = datetime.timezone.utc
21-
except AttributeError:
22-
# Python 2 lacks the datetime.timestamp() method.
23-
# We can do the timestamp math ourselves, but only if datetime.tzinfo is set.
24-
# Python 2 also lacks any predefined tzinfo classes (ex: datetime.timezone.utc),
25-
# so we must define our own.
26-
class _UTC(datetime.tzinfo):
27-
ZERO = datetime.timedelta(0)
28-
29-
def utcoffset(self, dt):
30-
return _UTC.ZERO
31-
32-
def tzname(self, dt):
33-
return "UTC"
34-
35-
def dst(self, dt):
36-
return _UTC.ZERO
37-
38-
_utc = _UTC()
3917

4018

4119
class AwsCredentials(NativeResource):
@@ -57,11 +35,11 @@ class AwsCredentials(NativeResource):
5735
__slots__ = ()
5836

5937
def __init__(self, access_key_id, secret_access_key, session_token=None):
60-
assert isinstance_str(access_key_id)
61-
assert isinstance_str(secret_access_key)
62-
assert isinstance_str(session_token) or session_token is None
38+
assert isinstance(access_key_id, str)
39+
assert isinstance(secret_access_key, str)
40+
assert isinstance(session_token, str) or session_token is None
6341

64-
super(AwsCredentials, self).__init__()
42+
super().__init__()
6543
self._binding = _awscrt.credentials_new(access_key_id, secret_access_key, session_token)
6644

6745
@classmethod
@@ -98,7 +76,7 @@ class AwsCredentialsProviderBase(NativeResource):
9876
__slots__ = ()
9977

10078
def __init__(self, binding=None):
101-
super(AwsCredentialsProviderBase, self).__init__()
79+
super().__init__()
10280

10381
if binding is None:
10482
# TODO: create binding type that lets native code call into python subclass
@@ -156,9 +134,9 @@ def new_static(cls, access_key_id, secret_access_key, session_token=None):
156134
Returns:
157135
AwsCredentialsProvider:
158136
"""
159-
assert isinstance_str(access_key_id)
160-
assert isinstance_str(secret_access_key)
161-
assert isinstance_str(session_token) or session_token is None
137+
assert isinstance(access_key_id, str)
138+
assert isinstance(secret_access_key, str)
139+
assert isinstance(session_token, str) or session_token is None
162140

163141
binding = _awscrt.credentials_provider_new_static(access_key_id, secret_access_key, session_token)
164142
return cls(binding)
@@ -345,28 +323,19 @@ def __init__(self,
345323
assert isinstance(algorithm, AwsSigningAlgorithm)
346324
assert isinstance(signature_type, AwsSignatureType)
347325
assert isinstance(credentials_provider, AwsCredentialsProviderBase)
348-
assert isinstance_str(region)
349-
assert isinstance_str(service)
326+
assert isinstance(region, str)
327+
assert isinstance(service, str)
350328
assert callable(should_sign_header) or should_sign_header is None
351329
assert signed_body_value is None or (isinstance(signed_body_value, str) and len(signed_body_value) > 0)
352330
assert isinstance(signed_body_header_type, AwsSignedBodyHeaderType)
353331
assert expiration_in_seconds is None or expiration_in_seconds > 0
354332

355-
super(AwsSigningConfig, self).__init__()
333+
super().__init__()
356334

357335
if date is None:
358-
date = datetime.datetime.now(_utc)
336+
date = datetime.datetime.now(datetime.timezone.utc)
359337

360-
try:
361-
timestamp = date.timestamp()
362-
except AttributeError:
363-
# Python 2 doesn't have datetime.timestamp() function.
364-
# If it did we could just call it from binding code instead of calculating it here.
365-
if date.tzinfo is None:
366-
timestamp = time.mktime(date.timetuple())
367-
else:
368-
epoch = datetime.datetime(1970, 1, 1, tzinfo=_utc)
369-
timestamp = (date - epoch).total_seconds()
338+
timestamp = date.timestamp()
370339

371340
self._priv_should_sign_cb = should_sign_header
372341

awscrt/crypto.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import _awscrt
55

66

7-
class Hash(object):
7+
class Hash:
88

99
def __init__(self, native_handle):
1010
"""
@@ -33,7 +33,7 @@ def digest(self, truncate_to=0):
3333
return _awscrt.hash_digest(self._hash, truncate_to)
3434

3535

36-
class HMAC(object):
36+
class HMAC:
3737
def __init__(self, native_handle):
3838
"""
3939
don't call me, I'm private

awscrt/http.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from __future__ import absolute_import
1111
import _awscrt
1212
from concurrent.futures import Future
13-
from awscrt import NativeResource, isinstance_str
13+
from awscrt import NativeResource
1414
import awscrt.exceptions
1515
from awscrt.io import ClientBootstrap, EventLoopGroup, DefaultHostResolver, InputStream, TlsConnectionOptions, SocketOptions
1616
from enum import IntEnum
@@ -30,7 +30,7 @@ class HttpConnectionBase(NativeResource):
3030
__slots__ = ('_shutdown_future', '_version')
3131

3232
def __init__(self):
33-
super(HttpConnectionBase, self).__init__()
33+
super().__init__()
3434

3535
self._shutdown_future = Future()
3636

@@ -113,7 +113,7 @@ def new(cls,
113113
Otherwise, it will contain an exception.
114114
"""
115115
assert isinstance(bootstrap, ClientBootstrap) or bootstrap is None
116-
assert isinstance_str(host_name)
116+
assert isinstance(host_name, str)
117117
assert isinstance(port, int)
118118
assert isinstance(tls_connection_options, TlsConnectionOptions) or tls_connection_options is None
119119
assert isinstance(socket_options, SocketOptions) or socket_options is None
@@ -226,7 +226,7 @@ class HttpStreamBase(NativeResource):
226226
__slots__ = ('_connection', '_completion_future', '_on_body_cb')
227227

228228
def __init__(self, connection, on_body=None):
229-
super(HttpStreamBase, self).__init__()
229+
super().__init__()
230230
self._connection = connection
231231
self._completion_future = Future()
232232
self._on_body_cb = on_body
@@ -268,7 +268,7 @@ def __init__(self, connection, request, on_response=None, on_body=None):
268268
assert callable(on_response) or on_response is None
269269
assert callable(on_body) or on_body is None
270270

271-
super(HttpClientStream, self).__init__(connection, on_body)
271+
super().__init__(connection, on_body)
272272

273273
self._on_response_cb = on_response
274274
self._response_status_code = None
@@ -318,7 +318,7 @@ class HttpMessageBase(NativeResource):
318318
def __init__(self, binding, headers, body_stream=None):
319319
assert isinstance(headers, HttpHeaders)
320320

321-
super(HttpMessageBase, self).__init__()
321+
super().__init__()
322322
self._binding = binding
323323
self._headers = headers
324324

@@ -364,7 +364,7 @@ def __init__(self, method='GET', path='/', headers=None, body_stream=None):
364364
headers = HttpHeaders()
365365

366366
binding = _awscrt.http_message_new_request(headers)
367-
super(HttpRequest, self).__init__(binding, headers, body_stream)
367+
super().__init__(binding, headers, body_stream)
368368
self.method = method
369369
self.path = path
370370

@@ -414,7 +414,7 @@ class HttpHeaders(NativeResource):
414414
__slots__ = ()
415415

416416
def __init__(self, name_value_pairs=None):
417-
super(HttpHeaders, self).__init__()
417+
super().__init__()
418418
self._binding = _awscrt.http_headers_new()
419419
if name_value_pairs:
420420
self.add_pairs(name_value_pairs)
@@ -435,8 +435,8 @@ def add(self, name, value):
435435
name (str): Name.
436436
value (str): Value.
437437
"""
438-
assert isinstance_str(name)
439-
assert isinstance_str(value)
438+
assert isinstance(name, str)
439+
assert isinstance(value, str)
440440
_awscrt.http_headers_add(self._binding, name, value)
441441

442442
def add_pairs(self, name_value_pairs):
@@ -456,8 +456,8 @@ def set(self, name, value):
456456
name (str): Name.
457457
value (str): Value.
458458
"""
459-
assert isinstance_str(name)
460-
assert isinstance_str(value)
459+
assert isinstance(name, str)
460+
assert isinstance(value, str)
461461
_awscrt.http_headers_set(self._binding, name, value)
462462

463463
def get_values(self, name):
@@ -470,7 +470,7 @@ def get_values(self, name):
470470
Returns:
471471
Iterator[Tuple[str, str]]:
472472
"""
473-
assert isinstance_str(name)
473+
assert isinstance(name, str)
474474
name = name.lower()
475475
for i in range(_awscrt.http_headers_count(self._binding)):
476476
name_i, value_i = _awscrt.http_headers_get_index(self._binding, i)
@@ -489,7 +489,7 @@ def get(self, name, default=None):
489489
Returns:
490490
str:
491491
"""
492-
assert isinstance_str(name)
492+
assert isinstance(name, str)
493493
return _awscrt.http_headers_get(self._binding, name, default)
494494

495495
def remove(self, name):
@@ -500,7 +500,7 @@ def remove(self, name):
500500
Args:
501501
name (str): Header name.
502502
"""
503-
assert isinstance_str(name)
503+
assert isinstance(name, str)
504504
_awscrt.http_headers_remove(self._binding, name)
505505

506506
def remove_value(self, name, value):
@@ -512,8 +512,8 @@ def remove_value(self, name, value):
512512
name (str): Name.
513513
value (str): Value.
514514
"""
515-
assert isinstance_str(name)
516-
assert isinstance_str(value)
515+
assert isinstance(name, str)
516+
assert isinstance(value, str)
517517
_awscrt.http_headers_remove_value(self._binding, name, value)
518518

519519
def clear(self):
@@ -542,7 +542,7 @@ class HttpProxyAuthenticationType(IntEnum):
542542
"""Username and password"""
543543

544544

545-
class HttpProxyOptions(object):
545+
class HttpProxyOptions:
546546
"""
547547
Proxy options for HTTP clients.
548548

0 commit comments

Comments
 (0)