Skip to content

Commit

Permalink
Remove support for python 2 (#164)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
graebm authored Sep 9, 2020
1 parent 297d89b commit 5f02655
Show file tree
Hide file tree
Showing 33 changed files with 177 additions and 284 deletions.
2 changes: 0 additions & 2 deletions .builder/actions/manylinux-ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
'cp35-cp35m',
'cp36-cp36m',
'cp37-cp37m',
'cp27-cp27m',
'cp27-cp27mu',
)


Expand Down
5 changes: 5 additions & 0 deletions .lgtm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extraction:
cpp:
index:
# not sure why cpp builds are using python 2, but this should stop it
build_command: "python3 setup.py build"
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
## AWS CRT Python

Python bindings for the AWS Common Runtime.
Python 3 bindings for the AWS Common Runtime.

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

## License

This library is licensed under the Apache 2.0 License.

## Minimum Requirements:
* Python 3.5+

## Installation

To install from pip:
````bash
python -m pip install awscrt
python3 -m pip install awscrt
````

To install from Github:
````bash
git clone https://github.com/awslabs/aws-crt-python.git
cd aws-crt-python
git submodule update --init
python -m pip install .
python3 -m pip install .
````

To use from your Python application, declare `awscrt` as a dependency in your `setup.py` file.
Expand Down
12 changes: 1 addition & 11 deletions awscrt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0.

from sys import version_info
from weakref import WeakSet

__all__ = [
Expand All @@ -13,7 +12,7 @@
]


class NativeResource(object):
class NativeResource:
"""
Base for classes that bind to a native type.
_binding is a python capsule referencing the native object.
Expand All @@ -33,12 +32,3 @@ class NativeResource(object):
def __init__(self):
if NativeResource._track_lifetime:
NativeResource._living.add(self)


def isinstance_str(x):
"""
Python 2/3 compatible way to check isinstance(x, str).
"""
if version_info[0] == 2:
return isinstance(x, basestring)
return isinstance(x, str)
59 changes: 14 additions & 45 deletions awscrt/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,13 @@

from __future__ import absolute_import
import _awscrt
from awscrt import isinstance_str, NativeResource
from awscrt import NativeResource
import awscrt.exceptions
from awscrt.http import HttpRequest
from awscrt.io import ClientBootstrap
from concurrent.futures import Future
import datetime
from enum import IntEnum
import time

try:
_utc = datetime.timezone.utc
except AttributeError:
# Python 2 lacks the datetime.timestamp() method.
# We can do the timestamp math ourselves, but only if datetime.tzinfo is set.
# Python 2 also lacks any predefined tzinfo classes (ex: datetime.timezone.utc),
# so we must define our own.
class _UTC(datetime.tzinfo):
ZERO = datetime.timedelta(0)

def utcoffset(self, dt):
return _UTC.ZERO

def tzname(self, dt):
return "UTC"

def dst(self, dt):
return _UTC.ZERO

_utc = _UTC()


class AwsCredentials(NativeResource):
Expand All @@ -57,11 +35,11 @@ class AwsCredentials(NativeResource):
__slots__ = ()

def __init__(self, access_key_id, secret_access_key, session_token=None):
assert isinstance_str(access_key_id)
assert isinstance_str(secret_access_key)
assert isinstance_str(session_token) or session_token is None
assert isinstance(access_key_id, str)
assert isinstance(secret_access_key, str)
assert isinstance(session_token, str) or session_token is None

super(AwsCredentials, self).__init__()
super().__init__()
self._binding = _awscrt.credentials_new(access_key_id, secret_access_key, session_token)

@classmethod
Expand Down Expand Up @@ -98,7 +76,7 @@ class AwsCredentialsProviderBase(NativeResource):
__slots__ = ()

def __init__(self, binding=None):
super(AwsCredentialsProviderBase, self).__init__()
super().__init__()

if binding is None:
# TODO: create binding type that lets native code call into python subclass
Expand Down Expand Up @@ -156,9 +134,9 @@ def new_static(cls, access_key_id, secret_access_key, session_token=None):
Returns:
AwsCredentialsProvider:
"""
assert isinstance_str(access_key_id)
assert isinstance_str(secret_access_key)
assert isinstance_str(session_token) or session_token is None
assert isinstance(access_key_id, str)
assert isinstance(secret_access_key, str)
assert isinstance(session_token, str) or session_token is None

binding = _awscrt.credentials_provider_new_static(access_key_id, secret_access_key, session_token)
return cls(binding)
Expand Down Expand Up @@ -345,28 +323,19 @@ def __init__(self,
assert isinstance(algorithm, AwsSigningAlgorithm)
assert isinstance(signature_type, AwsSignatureType)
assert isinstance(credentials_provider, AwsCredentialsProviderBase)
assert isinstance_str(region)
assert isinstance_str(service)
assert isinstance(region, str)
assert isinstance(service, str)
assert callable(should_sign_header) or should_sign_header is None
assert signed_body_value is None or (isinstance(signed_body_value, str) and len(signed_body_value) > 0)
assert isinstance(signed_body_header_type, AwsSignedBodyHeaderType)
assert expiration_in_seconds is None or expiration_in_seconds > 0

super(AwsSigningConfig, self).__init__()
super().__init__()

if date is None:
date = datetime.datetime.now(_utc)
date = datetime.datetime.now(datetime.timezone.utc)

try:
timestamp = date.timestamp()
except AttributeError:
# Python 2 doesn't have datetime.timestamp() function.
# If it did we could just call it from binding code instead of calculating it here.
if date.tzinfo is None:
timestamp = time.mktime(date.timetuple())
else:
epoch = datetime.datetime(1970, 1, 1, tzinfo=_utc)
timestamp = (date - epoch).total_seconds()
timestamp = date.timestamp()

self._priv_should_sign_cb = should_sign_header

Expand Down
4 changes: 2 additions & 2 deletions awscrt/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import _awscrt


class Hash(object):
class Hash:

def __init__(self, native_handle):
"""
Expand Down Expand Up @@ -33,7 +33,7 @@ def digest(self, truncate_to=0):
return _awscrt.hash_digest(self._hash, truncate_to)


class HMAC(object):
class HMAC:
def __init__(self, native_handle):
"""
don't call me, I'm private
Expand Down
36 changes: 18 additions & 18 deletions awscrt/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from __future__ import absolute_import
import _awscrt
from concurrent.futures import Future
from awscrt import NativeResource, isinstance_str
from awscrt import NativeResource
import awscrt.exceptions
from awscrt.io import ClientBootstrap, EventLoopGroup, DefaultHostResolver, InputStream, TlsConnectionOptions, SocketOptions
from enum import IntEnum
Expand All @@ -30,7 +30,7 @@ class HttpConnectionBase(NativeResource):
__slots__ = ('_shutdown_future', '_version')

def __init__(self):
super(HttpConnectionBase, self).__init__()
super().__init__()

self._shutdown_future = Future()

Expand Down Expand Up @@ -113,7 +113,7 @@ def new(cls,
Otherwise, it will contain an exception.
"""
assert isinstance(bootstrap, ClientBootstrap) or bootstrap is None
assert isinstance_str(host_name)
assert isinstance(host_name, str)
assert isinstance(port, int)
assert isinstance(tls_connection_options, TlsConnectionOptions) or tls_connection_options is None
assert isinstance(socket_options, SocketOptions) or socket_options is None
Expand Down Expand Up @@ -226,7 +226,7 @@ class HttpStreamBase(NativeResource):
__slots__ = ('_connection', '_completion_future', '_on_body_cb')

def __init__(self, connection, on_body=None):
super(HttpStreamBase, self).__init__()
super().__init__()
self._connection = connection
self._completion_future = Future()
self._on_body_cb = on_body
Expand Down Expand Up @@ -268,7 +268,7 @@ def __init__(self, connection, request, on_response=None, on_body=None):
assert callable(on_response) or on_response is None
assert callable(on_body) or on_body is None

super(HttpClientStream, self).__init__(connection, on_body)
super().__init__(connection, on_body)

self._on_response_cb = on_response
self._response_status_code = None
Expand Down Expand Up @@ -318,7 +318,7 @@ class HttpMessageBase(NativeResource):
def __init__(self, binding, headers, body_stream=None):
assert isinstance(headers, HttpHeaders)

super(HttpMessageBase, self).__init__()
super().__init__()
self._binding = binding
self._headers = headers

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

binding = _awscrt.http_message_new_request(headers)
super(HttpRequest, self).__init__(binding, headers, body_stream)
super().__init__(binding, headers, body_stream)
self.method = method
self.path = path

Expand Down Expand Up @@ -414,7 +414,7 @@ class HttpHeaders(NativeResource):
__slots__ = ()

def __init__(self, name_value_pairs=None):
super(HttpHeaders, self).__init__()
super().__init__()
self._binding = _awscrt.http_headers_new()
if name_value_pairs:
self.add_pairs(name_value_pairs)
Expand All @@ -435,8 +435,8 @@ def add(self, name, value):
name (str): Name.
value (str): Value.
"""
assert isinstance_str(name)
assert isinstance_str(value)
assert isinstance(name, str)
assert isinstance(value, str)
_awscrt.http_headers_add(self._binding, name, value)

def add_pairs(self, name_value_pairs):
Expand All @@ -456,8 +456,8 @@ def set(self, name, value):
name (str): Name.
value (str): Value.
"""
assert isinstance_str(name)
assert isinstance_str(value)
assert isinstance(name, str)
assert isinstance(value, str)
_awscrt.http_headers_set(self._binding, name, value)

def get_values(self, name):
Expand All @@ -470,7 +470,7 @@ def get_values(self, name):
Returns:
Iterator[Tuple[str, str]]:
"""
assert isinstance_str(name)
assert isinstance(name, str)
name = name.lower()
for i in range(_awscrt.http_headers_count(self._binding)):
name_i, value_i = _awscrt.http_headers_get_index(self._binding, i)
Expand All @@ -489,7 +489,7 @@ def get(self, name, default=None):
Returns:
str:
"""
assert isinstance_str(name)
assert isinstance(name, str)
return _awscrt.http_headers_get(self._binding, name, default)

def remove(self, name):
Expand All @@ -500,7 +500,7 @@ def remove(self, name):
Args:
name (str): Header name.
"""
assert isinstance_str(name)
assert isinstance(name, str)
_awscrt.http_headers_remove(self._binding, name)

def remove_value(self, name, value):
Expand All @@ -512,8 +512,8 @@ def remove_value(self, name, value):
name (str): Name.
value (str): Value.
"""
assert isinstance_str(name)
assert isinstance_str(value)
assert isinstance(name, str)
assert isinstance(value, str)
_awscrt.http_headers_remove_value(self._binding, name, value)

def clear(self):
Expand Down Expand Up @@ -542,7 +542,7 @@ class HttpProxyAuthenticationType(IntEnum):
"""Username and password"""


class HttpProxyOptions(object):
class HttpProxyOptions:
"""
Proxy options for HTTP clients.
Expand Down
Loading

0 comments on commit 5f02655

Please sign in to comment.