diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8bf26ca..5d10e24 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 6e7e6a8..f8aaba9 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -19,15 +19,15 @@ jobs: # see versions: https://github.com/actions/python-versions/releases/ steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest requests httpx six + pip install flake8 pytest requests httpx if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | diff --git a/requests_aws4auth/aws4auth.py b/requests_aws4auth/aws4auth.py index e0b55ff..5e2668a 100644 --- a/requests_aws4auth/aws4auth.py +++ b/requests_aws4auth/aws4auth.py @@ -7,9 +7,6 @@ # Licensed under the MIT License: # http://opensource.org/licenses/MIT - -from __future__ import unicode_literals - import hmac import hashlib import posixpath @@ -22,14 +19,9 @@ except ImportError: import collections as abc -try: - from urllib.parse import urlparse, parse_qs, quote, unquote -except ImportError: - from urlparse import urlparse, parse_qs - from urllib import quote, unquote +from urllib.parse import urlparse, parse_qs, quote, unquote from requests.auth import AuthBase -from six import PY2, text_type from .aws4signingkey import AWS4SigningKey from .exceptions import DateMismatchError, NoSecretKeyError, DateFormatError @@ -548,7 +540,7 @@ def encode_body(req): req -- Requests PreparedRequest object """ - if isinstance(req.body, text_type): + if isinstance(req.body, str): split = req.headers.get('content-type', 'text/plain').split(';') if len(split) == 2: ct, cs = split @@ -678,22 +670,13 @@ def amz_cano_path(self, path): if path.endswith('/') and not fixed_path.endswith('/'): fixed_path += '/' full_path = fixed_path - # If Python 2, switch to working entirely in str as quote() has problems - # with Unicode - if PY2: - full_path = full_path.encode('utf-8') - safe_chars = safe_chars.encode('utf-8') - qs = qs.encode('utf-8') # S3 seems to require unquoting first. 'host' service is used in # amz_testsuite tests if self.service in ['s3', 'host']: full_path = unquote(full_path) full_path = quote(full_path, safe=safe_chars) if qs: - qm = b'?' if PY2 else '?' - full_path = qm.join((full_path, qs)) - if PY2: - full_path = unicode(full_path) + full_path = '?'.join((full_path, qs)) return full_path @staticmethod @@ -707,13 +690,7 @@ def amz_cano_querystring(qs): """ safe_qs_unresvd = '-_.~' - # If Python 2, switch to working entirely in str - # as quote() has problems with Unicode - if PY2: - qs = qs.encode('utf-8') - safe_qs_unresvd = safe_qs_unresvd.encode() - space = b' ' if PY2 else ' ' - qs = qs.split(space)[0] + qs = qs.split(' ')[0] # prevent parse_qs from interpreting semicolon as an alternative delimiter to ampersand qs = qs.replace(';', '%3B') qs_items = {} @@ -727,8 +704,6 @@ def amz_cano_querystring(qs): for val in sorted(vals): qs_strings.append('='.join([name, val])) qs = '&'.join(qs_strings) - if PY2: - qs = unicode(qs) return qs @staticmethod diff --git a/requests_aws4auth/aws4signingkey.py b/requests_aws4auth/aws4signingkey.py index d69366a..c97d294 100644 --- a/requests_aws4auth/aws4signingkey.py +++ b/requests_aws4auth/aws4signingkey.py @@ -7,14 +7,10 @@ # Licensed under the MIT License: # http://opensource.org/licenses/MIT - -from __future__ import unicode_literals - import hmac import hashlib from warnings import warn from datetime import datetime -from six import text_type class AWS4SigningKey: @@ -127,7 +123,7 @@ def sign_sha256(key, msg): msg -- message to sign. unicode or bytes. """ - if isinstance(msg, text_type): + if isinstance(msg, str): msg = msg.encode('utf-8') return hmac.new(key, msg, hashlib.sha256).digest() diff --git a/requests_aws4auth/test/test_requests_aws4auth.py b/requests_aws4auth/test/test_requests_aws4auth.py index 46fe712..121f2bf 100644 --- a/requests_aws4auth/test/test_requests_aws4auth.py +++ b/requests_aws4auth/test/test_requests_aws4auth.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding: utf-8 """ Tests for requests-aws4auth package. @@ -25,25 +24,16 @@ # Licensed under the MIT License: # http://opensource.org/licenses/MIT - -from __future__ import unicode_literals, print_function - -import sys import os import unittest import re import hashlib import itertools -import json import warnings import datetime from errno import ENOENT -try: - from urllib.parse import quote, urlparse, urlunparse -except ImportError: - from urllib import quote - from urlparse import urlparse, urlunparse +from urllib.parse import quote, urlparse, urlunparse import requests import httpx @@ -51,8 +41,6 @@ from requests_aws4auth import AWS4Auth from requests_aws4auth.aws4signingkey import AWS4SigningKey from requests_aws4auth.exceptions import DateFormatError, NoSecretKeyError -from six import PY2, u - class SimpleNamespace: pass @@ -113,10 +101,10 @@ def load_testsuite_data(path): 'from here: http://docs.aws.amazon.com/general/latest/gr/' 'samples/aws4_testsuite.zip') if not os.path.exists(path): - raise IOError(ENOENT, errmsg) + raise OSError(ENOENT, errmsg) files = sorted(os.listdir(path)) if not files: - raise IOError(ENOENT, errmsg) + raise OSError(ENOENT, errmsg) grouped = itertools.groupby(files, lambda x: os.path.splitext(x)[0]) data = {} for group_name, items in grouped: @@ -128,12 +116,8 @@ def load_testsuite_data(path): for item in items: filepath = os.path.join(path, item) file_ext = os.path.splitext(item)[1] - if PY2: - with open(filepath, 'U') as f: - content = unicode(f.read(), encoding='utf-8') - else: - with open(filepath, encoding='utf-8') as f: - content = f.read() + with open(filepath, encoding='utf-8') as f: + content = f.read() group[file_ext] = content data[group_name] = group return data @@ -141,7 +125,7 @@ def load_testsuite_data(path): try: amz_aws4_testsuite = AmzAws4TestSuite() -except IOError as e: +except OSError as e: if e.errno == ENOENT: amz_aws4_testsuite = None else: @@ -162,7 +146,7 @@ def request_from_text(text): for idx, line in enumerate(lines[1:], start=1): if not line: break - hdr, val = [item.strip() for item in line.split(':', 1)] + hdr, val = (item.strip() for item in line.split(':', 1)) hdr = hdr.lower() vals = headers.setdefault(hdr, []) vals.append(val) @@ -239,14 +223,8 @@ def test_amz_date_warning(self): warnings.resetwarnings() with warnings.catch_warnings(record=True) as w: obj = AWS4SigningKey('secret_key', 'region', 'service') - if PY2: - warnings.simplefilter('always') - obj.amz_date - self.assertEqual(len(w), 1) - self.assertEqual(w[-1].category, DeprecationWarning) - else: - warnings.simplefilter('ignore') - self.assertWarns(DeprecationWarning, getattr, obj, 'amz_date') + warnings.simplefilter('ignore') + self.assertWarns(DeprecationWarning, getattr, obj, 'amz_date') def test_sign_sha256_unicode_msg(self): key = b'The quick brown fox jumps over the lazy dog' @@ -257,7 +235,7 @@ def test_sign_sha256_unicode_msg(self): 142, 77, 204, 122, 185, 19, 38, 15, 145, 249, 113, 69, 178, 30, 131, 244, 230, 190, 246, 23] hsh = AWS4SigningKey.sign_sha256(key, msg) - hsh = [ord(x) for x in hsh] if PY2 else list(hsh) + hsh = list(hsh) self.assertEqual(hsh, expected) def test_sign_sha256_bytes_msg(self): @@ -269,7 +247,7 @@ def test_sign_sha256_bytes_msg(self): 142, 77, 204, 122, 185, 19, 38, 15, 145, 249, 113, 69, 178, 30, 131, 244, 230, 190, 246, 23] hsh = AWS4SigningKey.sign_sha256(key, msg) - hsh = [ord(x) for x in hsh] if PY2 else list(hsh) + hsh = list(hsh) self.assertEqual(hsh, expected) def test_signing_key_phases(self): @@ -296,7 +274,7 @@ def test_signing_key_phases(self): result = AWS4SigningKey.generate_key(secret_key, region, service, date, intermediates=True) for i, hsh in enumerate(result): - hsh = [ord(x) for x in hsh] if PY2 else list(hsh) + hsh = list(hsh) self.assertEqual(hsh, expected[i], msg='Item number {}'.format(i)) def test_generate_key(self): @@ -313,7 +291,7 @@ def test_generate_key(self): 171, 12, 225, 248, 46, 105, 41, 194, 98, 237, 21, 229, 169, 76, 144, 239, 209, 227, 176, 231] key = AWS4SigningKey.generate_key(secret_key, region, service, date) - key = [ord(x) for x in key] if PY2 else list(key) + key = list(key) self.assertEqual(key, expected) def test_instantiation_generate_key(self): @@ -330,7 +308,7 @@ def test_instantiation_generate_key(self): 171, 12, 225, 248, 46, 105, 41, 194, 98, 237, 21, 229, 169, 76, 144, 239, 209, 227, 176, 231] key = AWS4SigningKey(secret_key, region, service, date).key - key = [ord(x) for x in key] if PY2 else list(key) + key = list(key) self.assertEqual(key, expected) @@ -338,7 +316,7 @@ class AWS4Auth_Instantiate_Test(unittest.TestCase): def test_instantiate_from_args(self): test_date = datetime.datetime.utcnow().strftime('%Y%m%d') - test_inc_hdrs = set(['a', 'b', 'c']) + test_inc_hdrs = {'a', 'b', 'c'} auth = AWS4Auth('access_id', 'secret_key', 'region', @@ -497,7 +475,7 @@ def test_get_request_date__date_only(self): 'Sun Jan 5 01:01:01 1980': (1980, 1, 5), '1985-02-06T01:01:01+01:00': (1985, 2, 6), } - tests = dict([(k, datetime.date(*v)) for k, v in tests.items()]) + tests = {k: datetime.date(*v) for k, v in tests.items()} for date_str, check in tests.items(): req = requests.Request('GET', 'http://blah.com') req = req.prepare() diff --git a/setup.py b/setup.py index 8626aea..8f3a0ab 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,11 @@ import os -import io import codecs import re from setuptools import setup def read(*names): - with io.open( + with open( os.path.join(os.path.dirname(__file__), *names), encoding='utf-8' ) as f: @@ -43,7 +42,7 @@ def find_version(*file_paths): download_url=('https://github.com/tedder/requests-aws4auth/tarball/' + version), license='MIT License', keywords='requests authentication amazon web services aws s3 REST', - install_requires=['requests', 'six'], + install_requires=['requests'], extras_require={ 'httpx': ['httpx',] },