diff --git a/gnu/local.mk b/gnu/local.mk index 584684768e9..720c78f049b 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -2054,6 +2054,7 @@ dist_patch_DATA = \ %D%/packages/patches/python-feedparser-missing-import.patch \ %D%/packages/patches/python-louvain-fix-test.patch \ %D%/packages/patches/python-matplotlib-fix-legend-loc-best-test.patch \ + %D%/packages/patches/python-mohawk-pytest.patch \ %D%/packages/patches/python-numpy-gcc-14.patch \ %D%/packages/patches/python-random2-getrandbits-test.patch \ %D%/packages/patches/python-pillow-use-zlib-1.3.patch \ diff --git a/gnu/packages/patches/python-mohawk-pytest.patch b/gnu/packages/patches/python-mohawk-pytest.patch new file mode 100644 index 00000000000..cc1c56f58d3 --- /dev/null +++ b/gnu/packages/patches/python-mohawk-pytest.patch @@ -0,0 +1,1018 @@ +From ed2ec6f0243249d3673a23d99aefc919e24cdeca Mon Sep 17 00:00:00 2001 +From: Pyrox +Date: Fri, 2 Aug 2024 14:40:37 -0400 +Subject: [PATCH 1/4] autoconvert nose assertions with nose2pytest + +--- + mohawk/tests.py | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/mohawk/tests.py b/mohawk/tests.py +index e680cf8..505c7d8 100644 +--- a/mohawk/tests.py ++++ b/mohawk/tests.py +@@ -288,8 +288,8 @@ def test_expired_exception_reports_localtime(self): + except: + etype, exc, tb = sys.exc_info() + +- eq_(type(exc), TokenExpired) +- eq_(exc.localtime_in_seconds, now) ++ assert type(exc) == TokenExpired ++ assert exc.localtime_in_seconds == now + + def test_localtime_offset(self): + now = utc_now() - 120 +@@ -371,7 +371,7 @@ def test_ext_with_equality_sign(self): + sn = self.Sender(ext="foo=bar&foo2=bar2;foo3=bar3") + self.receive(sn.request_header) + parsed = parse_authorization_header(sn.request_header) +- eq_(parsed['ext'], "foo=bar&foo2=bar2;foo3=bar3") ++ assert parsed['ext'] == "foo=bar&foo2=bar2;foo3=bar3" + + @raises(HawkFail) + def test_non_hawk_scheme(self): +@@ -385,7 +385,7 @@ def test_ext_with_all_valid_characters(self): + valid_characters = "!#$%&'()*+,-./:;<=>?@[]^_`{|}~ azAZ09_" + sender = self.Sender(ext=valid_characters) + parsed = parse_authorization_header(sender.request_header) +- eq_(parsed['ext'], valid_characters) ++ assert parsed['ext'] == valid_characters + + @raises(BadHeaderValue) + def test_ext_with_illegal_chars(self): +@@ -421,7 +421,7 @@ def test_app_ok(self): + sn = self.Sender(app=app) + self.receive(sn.request_header) + parsed = parse_authorization_header(sn.request_header) +- eq_(parsed['app'], app) ++ assert parsed['app'] == app + + @raises(MacMismatch) + def test_tampered_app(self): +@@ -435,7 +435,7 @@ def test_dlg_ok(self): + sn = self.Sender(dlg=dlg) + self.receive(sn.request_header) + parsed = parse_authorization_header(sn.request_header) +- eq_(parsed['dlg'], dlg) ++ assert parsed['dlg'] == dlg + + @raises(MacMismatch) + def test_tampered_dlg(self): +@@ -589,7 +589,7 @@ def test_respond_with_expired_ts(self): + calculated = calculate_ts_mac(fn(), self.credentials) + if isinstance(calculated, six.binary_type): + calculated = calculated.decode('ascii') +- eq_(hdr['tsm'], calculated) ++ assert hdr['tsm'] == calculated + raise + + def test_respond_with_bad_ts_skew_ok(self): +@@ -611,7 +611,7 @@ def test_respond_with_ext(self): + ext = 'custom-ext' + self.respond(ext=ext) + header = parse_authorization_header(self.receiver.response_header) +- eq_(header['ext'], ext) ++ assert header['ext'] == ext + + @raises(MacMismatch) + def test_respond_with_wrong_app(self): +@@ -854,7 +854,7 @@ def test_bewit(self): + bewit = get_bewit(res) + + expected = '123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' +- eq_(b64decode(bewit).decode('ascii'), expected) ++ assert b64decode(bewit).decode('ascii') == expected + + def test_bewit_with_binary_id(self): + # Check for exceptions in get_bewit call with binary id +@@ -877,7 +877,7 @@ def test_bewit_with_ext(self): + bewit = get_bewit(res) + + expected = '123456\\1356420707\\kscxwNR2tJpP1T1zDLNPbB5UiKIU9tOSJXTUdG7X9h8=\\xandyandz' +- eq_(b64decode(bewit).decode('ascii'), expected) ++ assert b64decode(bewit).decode('ascii') == expected + + @raises(BadHeaderValue) + def test_bewit_with_invalid_ext(self): +@@ -905,7 +905,7 @@ def test_bewit_with_port(self): + bewit = get_bewit(res) + + expected = '123456\\1356420707\\hZbJ3P2cKEo4ky0C8jkZAkRyCZueg4WSNbxV7vq3xHU=\\xandyandz' +- eq_(b64decode(bewit).decode('ascii'), expected) ++ assert b64decode(bewit).decode('ascii') == expected + + @raises(ValueError) + def test_bewit_with_nonce(self): + +From 66157c7efbf6b0d18c30a9ffe5dfd84bef27bd3a Mon Sep 17 00:00:00 2001 +From: Pyrox +Date: Fri, 2 Aug 2024 15:20:34 -0400 +Subject: [PATCH 2/4] nose.raises -> unittest.assertRaises + +--- + mohawk/tests.py | 385 ++++++++++++++++++++++++------------------------ + 1 file changed, 191 insertions(+), 194 deletions(-) + +diff --git a/mohawk/tests.py b/mohawk/tests.py +index 505c7d8..801c1dd 100644 +--- a/mohawk/tests.py ++++ b/mohawk/tests.py +@@ -1,10 +1,8 @@ + import sys + import warnings +-from unittest import TestCase ++from unittest import TestCase, mock + from base64 import b64decode, urlsafe_b64encode + +-import mock +-from nose.tools import eq_, raises + import six + + from . import Receiver, Sender +@@ -60,27 +58,27 @@ def credentials_map(self, id): + + class TestConfig(Base): + +- @raises(InvalidCredentials) + def test_no_id(self): + c = self.credentials.copy() + del c['id'] +- validate_credentials(c) ++ with self.assertRaises(InvalidCredentials): ++ validate_credentials(c) + +- @raises(InvalidCredentials) + def test_no_key(self): + c = self.credentials.copy() + del c['key'] +- validate_credentials(c) ++ with self.assertRaises(InvalidCredentials): ++ validate_credentials(c) + +- @raises(InvalidCredentials) + def test_no_algo(self): + c = self.credentials.copy() + del c['algorithm'] +- validate_credentials(c) ++ with self.assertRaises(InvalidCredentials): ++ validate_credentials(c) + +- @raises(InvalidCredentials) + def test_no_credentials(self): +- validate_credentials(None) ++ with self.assertRaises(InvalidCredentials): ++ validate_credentials(None) + + def test_non_dict_credentials(self): + class WeirdThing(object): +@@ -144,10 +142,10 @@ def test_post_content_type_with_trailing_charset(self): + self.receive(sn.request_header, method=method, content=content, + content_type='application/json; charset=other') + +- @raises(MissingContent) + def test_missing_payload_details(self): +- self.Sender(method='POST', content=EmptyValue, +- content_type=EmptyValue) ++ with self.assertRaises(MissingContent): ++ self.Sender(method='POST', content=EmptyValue, ++ content_type=EmptyValue) + + def test_skip_payload_hashing(self): + method = 'POST' +@@ -193,73 +191,72 @@ def test_empty_payload_hashing_accept_untrusted(self): + content_type=content_type, + accept_untrusted_content=True) + +- @raises(MissingContent) + def test_cannot_skip_content_only(self): +- self.Sender(method='POST', content=EmptyValue, +- content_type='application/json') ++ with self.assertRaises(MissingContent): ++ self.Sender(method='POST', content=EmptyValue, ++ content_type='application/json') + +- @raises(MissingContent) + def test_cannot_skip_content_type_only(self): +- self.Sender(method='POST', content='{"foo": "bar"}', +- content_type=EmptyValue) ++ with self.assertRaises(MissingContent): ++ self.Sender(method='POST', content='{"foo": "bar"}', ++ content_type=EmptyValue) + +- @raises(MacMismatch) + def test_tamper_with_host(self): + sn = self.Sender() +- self.receive(sn.request_header, url='http://TAMPERED-WITH.com') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, url='http://TAMPERED-WITH.com') + +- @raises(MacMismatch) + def test_tamper_with_method(self): + sn = self.Sender(method='GET') +- self.receive(sn.request_header, method='POST') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, method='POST') + +- @raises(MacMismatch) + def test_tamper_with_path(self): + sn = self.Sender() +- self.receive(sn.request_header, +- url='http://site.com/TAMPERED?bar=1') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, ++ url='http://site.com/TAMPERED?bar=1') + +- @raises(MacMismatch) + def test_tamper_with_query(self): + sn = self.Sender() +- self.receive(sn.request_header, +- url='http://site.com/foo?bar=TAMPERED') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, ++ url='http://site.com/foo?bar=TAMPERED') + +- @raises(MacMismatch) + def test_tamper_with_scheme(self): + sn = self.Sender() +- self.receive(sn.request_header, url='https://site.com/foo?bar=1') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, url='https://site.com/foo?bar=1') + +- @raises(MacMismatch) + def test_tamper_with_port(self): + sn = self.Sender() +- self.receive(sn.request_header, +- url='http://site.com:8000/foo?bar=1') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, ++ url='http://site.com:8000/foo?bar=1') + +- @raises(MisComputedContentHash) + def test_tamper_with_content(self): + sn = self.Sender() +- self.receive(sn.request_header, content='stuff=nope') ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(sn.request_header, content='stuff=nope') + + def test_non_ascii_content(self): + content = u'Ivan Kristi\u0107' + sn = self.Sender(content=content) + self.receive(sn.request_header, content=content) + +- @raises(MacMismatch) + def test_tamper_with_content_type(self): + sn = self.Sender(method='POST') +- self.receive(sn.request_header, content_type='application/json') ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header, content_type='application/json') + +- @raises(AlreadyProcessed) + def test_nonce_fail(self): + + def seen_nonce(id, nonce, ts): + return True + + sn = self.Sender() +- +- self.receive(sn.request_header, seen_nonce=seen_nonce) ++ with self.assertRaises(AlreadyProcessed): ++ self.receive(sn.request_header, seen_nonce=seen_nonce) + + def test_nonce_ok(self): + +@@ -269,11 +266,11 @@ def seen_nonce(id, nonce, ts): + sn = self.Sender(seen_nonce=seen_nonce) + self.receive(sn.request_header) + +- @raises(TokenExpired) + def test_expired_ts(self): + now = utc_now() - 120 + sn = self.Sender(_timestamp=now) +- self.receive(sn.request_header) ++ with self.assertRaises(TokenExpired): ++ self.receive(sn.request_header) + + def test_expired_exception_reports_localtime(self): + now = utc_now() +@@ -303,13 +300,12 @@ def test_localtime_skew(self): + # Without an offset this will raise an expired exception. + self.receive(sn.request_header, timestamp_skew_in_seconds=120) + +- @raises(MacMismatch) + def test_hash_tampering(self): + sn = self.Sender() + header = sn.request_header.replace('hash="', 'hash="nope') +- self.receive(header) ++ with self.assertRaises(MacMismatch): ++ self.receive(header) + +- @raises(MacMismatch) + def test_bad_secret(self): + cfg = { + 'id': 'my-hawk-id', +@@ -317,55 +313,56 @@ def test_bad_secret(self): + 'algorithm': 'sha256', + } + sn = self.Sender(credentials=cfg) +- self.receive(sn.request_header) ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header) + +- @raises(MacMismatch) + def test_unexpected_algorithm(self): + cr = self.credentials.copy() + cr['algorithm'] = 'sha512' + sn = self.Sender(credentials=cr) + + # Validate with mismatched credentials (sha256). +- self.receive(sn.request_header) ++ with self.assertRaises(MacMismatch): ++ self.receive(sn.request_header) + +- @raises(InvalidCredentials) + def test_invalid_credentials(self): + cfg = self.credentials.copy() + # Create an invalid credentials. + del cfg['algorithm'] + +- self.Sender(credentials=cfg) ++ with self.assertRaises(InvalidCredentials): ++ self.Sender(credentials=cfg) + +- @raises(CredentialsLookupError) + def test_unknown_id(self): + cr = self.credentials.copy() + cr['id'] = 'someone-else' + sn = self.Sender(credentials=cr) + +- self.receive(sn.request_header) ++ with self.assertRaises(CredentialsLookupError): ++ self.receive(sn.request_header) + +- @raises(MacMismatch) + def test_bad_ext(self): + sn = self.Sender(ext='my external data') + + header = sn.request_header.replace('my external data', 'TAMPERED') +- self.receive(header) ++ with self.assertRaises(MacMismatch): ++ self.receive(header) + +- @raises(BadHeaderValue) + def test_duplicate_keys(self): + sn = self.Sender(ext='someext') + header = sn.request_header + ', ext="otherext"' +- self.receive(header) ++ with self.assertRaises(BadHeaderValue): ++ self.receive(header) + +- @raises(BadHeaderValue) + def test_ext_with_quotes(self): +- sn = self.Sender(ext='quotes=""') +- self.receive(sn.request_header) ++ with self.assertRaises(BadHeaderValue): ++ sn = self.Sender(ext='quotes=""') ++ self.receive(sn.request_header) + +- @raises(BadHeaderValue) + def test_ext_with_new_line(self): +- sn = self.Sender(ext="new line \n in the middle") +- self.receive(sn.request_header) ++ with self.assertRaises(BadHeaderValue): ++ sn = self.Sender(ext="new line \n in the middle") ++ self.receive(sn.request_header) + + def test_ext_with_equality_sign(self): + sn = self.Sender(ext="foo=bar&foo2=bar2;foo3=bar3") +@@ -373,13 +370,13 @@ def test_ext_with_equality_sign(self): + parsed = parse_authorization_header(sn.request_header) + assert parsed['ext'] == "foo=bar&foo2=bar2;foo3=bar3" + +- @raises(HawkFail) + def test_non_hawk_scheme(self): +- parse_authorization_header('Basic user:base64pw') ++ with self.assertRaises(HawkFail): ++ parse_authorization_header('Basic user:base64pw') + +- @raises(HawkFail) + def test_invalid_key(self): +- parse_authorization_header('Hawk mac="validmac" unknownkey="value"') ++ with self.assertRaises(HawkFail): ++ parse_authorization_header('Hawk mac="validmac" unknownkey="value"') + + def test_ext_with_all_valid_characters(self): + valid_characters = "!#$%&'()*+,-./:;<=>?@[]^_`{|}~ azAZ09_" +@@ -387,9 +384,9 @@ def test_ext_with_all_valid_characters(self): + parsed = parse_authorization_header(sender.request_header) + assert parsed['ext'] == valid_characters + +- @raises(BadHeaderValue) + def test_ext_with_illegal_chars(self): +- self.Sender(ext="something like \t is illegal") ++ with self.assertRaises(BadHeaderValue): ++ self.Sender(ext="something like \t is illegal") + + def test_unparseable_header(self): + try: +@@ -401,20 +398,20 @@ def test_unparseable_header(self): + else: + self.fail('should raise') + +- @raises(BadHeaderValue) + def test_ext_with_illegal_unicode(self): +- self.Sender(ext=u'Ivan Kristi\u0107') ++ with self.assertRaises(BadHeaderValue): ++ self.Sender(ext=u'Ivan Kristi\u0107') + +- @raises(BadHeaderValue) + def test_too_long_header(self): + sn = self.Sender(ext='a'*5000) +- self.receive(sn.request_header) ++ with self.assertRaises(BadHeaderValue): ++ self.receive(sn.request_header) + +- @raises(BadHeaderValue) + def test_ext_with_illegal_utf8(self): + # This isn't allowed because the escaped byte chars are out of + # range. +- self.Sender(ext=u'Ivan Kristi\u0107'.encode('utf8')) ++ with self.assertRaises(BadHeaderValue): ++ self.Sender(ext=u'Ivan Kristi\u0107'.encode('utf8')) + + def test_app_ok(self): + app = 'custom-app' +@@ -423,12 +420,12 @@ def test_app_ok(self): + parsed = parse_authorization_header(sn.request_header) + assert parsed['app'] == app + +- @raises(MacMismatch) + def test_tampered_app(self): + app = 'custom-app' + sn = self.Sender(app=app) + header = sn.request_header.replace(app, 'TAMPERED-WITH') +- self.receive(header) ++ with self.assertRaises(MacMismatch): ++ self.receive(header) + + def test_dlg_ok(self): + dlg = 'custom-dlg' +@@ -437,12 +434,12 @@ def test_dlg_ok(self): + parsed = parse_authorization_header(sn.request_header) + assert parsed['dlg'] == dlg + +- @raises(MacMismatch) + def test_tampered_dlg(self): + dlg = 'custom-dlg' + sn = self.Sender(dlg=dlg, app='some-app') + header = sn.request_header.replace(dlg, 'TAMPERED-WITH') +- self.receive(header) ++ with self.assertRaises(MacMismatch): ++ self.receive(header) + + def test_file_content(self): + method = "POST" +@@ -456,12 +453,12 @@ def test_binary_file_content(self): + sn = self.Sender(method, content=content) + self.receive(sn.request_header, method=method, content=content.getvalue()) + +- @raises(MisComputedContentHash) + def test_bad_file_content(self): + method = "POST" + content = six.BytesIO(b"FILE CONTENT") + sn = self.Sender(method, content=content) +- self.receive(sn.request_header, method=method, content="BAD FILE CONTENT") ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(sn.request_header, method=method, content="BAD FILE CONTENT") + + + class TestReceiver(Base): +@@ -508,10 +505,10 @@ def respond(self, **kw): + + return receiver.response_header + +- @raises(InvalidCredentials) + def test_invalid_credentials_lookup(self): + # Return invalid credentials. +- self.receive(credentials_map=lambda *a: {}) ++ with self.assertRaises(InvalidCredentials): ++ self.receive(credentials_map=lambda *a: {}) + + def test_get_ok(self): + method = 'GET' +@@ -523,49 +520,49 @@ def test_post_ok(self): + self.receive(method=method) + self.respond() + +- @raises(MisComputedContentHash) + def test_respond_with_wrong_content(self): + self.receive() +- self.respond(content='real content', +- accept_kw=dict(content='TAMPERED WITH')) ++ with self.assertRaises(MisComputedContentHash): ++ self.respond(content='real content', ++ accept_kw=dict(content='TAMPERED WITH')) + +- @raises(MisComputedContentHash) + def test_respond_with_wrong_content_type(self): + self.receive() +- self.respond(content_type='text/html', +- accept_kw=dict(content_type='application/json')) ++ with self.assertRaises(MisComputedContentHash): ++ self.respond(content_type='text/html', ++ accept_kw=dict(content_type='application/json')) + +- @raises(MissingAuthorization) + def test_missing_authorization(self): +- Receiver(lambda id: self.credentials, None, '/', 'GET') ++ with self.assertRaises(MissingAuthorization): ++ Receiver(lambda id: self.credentials, None, '/', 'GET') + +- @raises(MacMismatch) + def test_respond_with_wrong_url(self): +- self.receive(url='http://fakesite.com') +- wrong_receiver = self.receiver ++ with self.assertRaises(MacMismatch): ++ self.receive(url='http://fakesite.com') ++ wrong_receiver = self.receiver + +- self.receive(url='http://realsite.com') ++ self.receive(url='http://realsite.com') + +- self.respond(receiver=wrong_receiver) ++ self.respond(receiver=wrong_receiver) + +- @raises(MacMismatch) + def test_respond_with_wrong_method(self): +- self.receive(method='GET') +- wrong_receiver = self.receiver ++ with self.assertRaises(MacMismatch): ++ self.receive(method='GET') ++ wrong_receiver = self.receiver + +- self.receive(method='POST') ++ self.receive(method='POST') + +- self.respond(receiver=wrong_receiver) ++ self.respond(receiver=wrong_receiver) + +- @raises(MacMismatch) + def test_respond_with_wrong_nonce(self): +- self.receive(sender_kw=dict(nonce='another-nonce')) +- wrong_receiver = self.receiver ++ with self.assertRaises(MacMismatch): ++ self.receive(sender_kw=dict(nonce='another-nonce')) ++ wrong_receiver = self.receiver + +- self.receive() ++ self.receive() + +- # The nonce must match the one sent in the original request. +- self.respond(receiver=wrong_receiver) ++ # The nonce must match the one sent in the original request. ++ self.respond(receiver=wrong_receiver) + + def test_respond_with_unhashed_content(self): + self.receive() +@@ -574,23 +571,23 @@ def test_respond_with_unhashed_content(self): + content_type=None, + accept_kw=dict(accept_untrusted_content=True)) + +- @raises(TokenExpired) + def test_respond_with_expired_ts(self): + self.receive() + hdr = self.receiver.respond(content='', content_type='') + +- with mock.patch('mohawk.base.utc_now') as fn: +- fn.return_value = 0 # force an expiry +- try: +- self.sender.accept_response(hdr, content='', content_type='') +- except TokenExpired: +- etype, exc, tb = sys.exc_info() +- hdr = parse_authorization_header(exc.www_authenticate) +- calculated = calculate_ts_mac(fn(), self.credentials) +- if isinstance(calculated, six.binary_type): +- calculated = calculated.decode('ascii') +- assert hdr['tsm'] == calculated +- raise ++ with self.assertRaises(TokenExpired): ++ with mock.patch('mohawk.base.utc_now') as fn: ++ fn.return_value = 0 # force an expiry ++ try: ++ self.sender.accept_response(hdr, content='', content_type='') ++ except TokenExpired: ++ etype, exc, tb = sys.exc_info() ++ hdr = parse_authorization_header(exc.www_authenticate) ++ calculated = calculate_ts_mac(fn(), self.credentials) ++ if isinstance(calculated, six.binary_type): ++ calculated = calculated.decode('ascii') ++ assert hdr['tsm'] == calculated ++ raise + + def test_respond_with_bad_ts_skew_ok(self): + now = utc_now() - 120 +@@ -613,7 +610,6 @@ def test_respond_with_ext(self): + header = parse_authorization_header(self.receiver.response_header) + assert header['ext'] == ext + +- @raises(MacMismatch) + def test_respond_with_wrong_app(self): + self.receive(sender_kw=dict(app='TAMPERED-WITH', dlg='delegation')) + self.receiver.respond(content='', content_type='') +@@ -621,10 +617,10 @@ def test_respond_with_wrong_app(self): + + self.receive(sender_kw=dict(app='real-app', dlg='delegation')) + +- self.sender.accept_response(wrong_receiver.response_header, +- content='', content_type='') ++ with self.assertRaises(MacMismatch): ++ self.sender.accept_response(wrong_receiver.response_header, ++ content='', content_type='') + +- @raises(MacMismatch) + def test_respond_with_wrong_dlg(self): + self.receive(sender_kw=dict(app='app', dlg='TAMPERED-WITH')) + self.receiver.respond(content='', content_type='') +@@ -632,27 +628,28 @@ def test_respond_with_wrong_dlg(self): + + self.receive(sender_kw=dict(app='app', dlg='real-dlg')) + +- self.sender.accept_response(wrong_receiver.response_header, +- content='', content_type='') ++ with self.assertRaises(MacMismatch): ++ self.sender.accept_response(wrong_receiver.response_header, ++ content='', content_type='') + +- @raises(MacMismatch) + def test_receive_wrong_method(self): + self.receive(method='GET') + wrong_sender = self.sender +- self.receive(method='POST', sender=wrong_sender) ++ with self.assertRaises(MacMismatch): ++ self.receive(method='POST', sender=wrong_sender) + +- @raises(MacMismatch) + def test_receive_wrong_url(self): + self.receive(url='http://fakesite.com/') + wrong_sender = self.sender +- self.receive(url='http://realsite.com/', sender=wrong_sender) ++ with self.assertRaises(MacMismatch): ++ self.receive(url='http://realsite.com/', sender=wrong_sender) + +- @raises(MisComputedContentHash) + def test_receive_wrong_content(self): + self.receive(sender_kw=dict(content='real request'), + content='real request') + wrong_sender = self.sender +- self.receive(content='TAMPERED WITH', sender=wrong_sender) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content='TAMPERED WITH', sender=wrong_sender) + + def test_expected_unhashed_empty_content(self): + # This test sets up a scenario where the receiver will receive empty +@@ -669,7 +666,6 @@ def test_expected_unhashed_empty_content(self): + content_type=EmptyValue, + always_hash_content=False)) + +- @raises(MisComputedContentHash) + def test_expected_unhashed_empty_content_with_content_type(self): + # This test sets up a scenario where the receiver will receive an + # empty content string and no content hash in the auth header, but +@@ -677,13 +673,13 @@ def test_expected_unhashed_empty_content_with_content_type(self): + # This is to confirm that the hash is calculated and compared (to the + # hash of mock empty payload, which should fail) when it appears that + # the sender has sent a 0-length payload body. +- self.receive(content='', +- content_type='text/plain', +- sender_kw=dict(content=EmptyValue, +- content_type=EmptyValue, +- always_hash_content=False)) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content='', ++ content_type='text/plain', ++ sender_kw=dict(content=EmptyValue, ++ content_type=EmptyValue, ++ always_hash_content=False)) + +- @raises(MisComputedContentHash) + def test_expected_unhashed_content_with_empty_content_type(self): + # This test sets up a scenario where the receiver will receive some + # content but the empty string for the content_type and no content hash +@@ -691,11 +687,12 @@ def test_expected_unhashed_content_with_empty_content_type(self): + # This is to confirm that the hash is calculated and compared (to the + # hash of mock empty payload, which should fail) when the sender has + # sent unhashed content. +- self.receive(content='some content', +- content_type='', +- sender_kw=dict(content=EmptyValue, +- content_type=EmptyValue, +- always_hash_content=False)) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content='some content', ++ content_type='', ++ sender_kw=dict(content=EmptyValue, ++ content_type=EmptyValue, ++ always_hash_content=False)) + + def test_empty_content_with_content_type(self): + # This test sets up a scenario where the receiver will receive an +@@ -719,7 +716,6 @@ def test_expected_unhashed_no_content(self): + content_type=EmptyValue, + always_hash_content=False)) + +- @raises(MisComputedContentHash) + def test_expected_unhashed_no_content_with_content_type(self): + # This test sets up a scenario where the receiver will receive None for + # content and no content hash in the auth header, but some value for +@@ -729,13 +725,13 @@ def test_expected_unhashed_no_content_with_content_type(self): + # hash in the request to compare against. While this may not be in + # accordance with the js reference spec, it's the safest (ie. most + # secure) way of handling this bizarre set of circumstances. +- self.receive(content=None, +- content_type='text/plain', +- sender_kw=dict(content=EmptyValue, +- content_type=EmptyValue, +- always_hash_content=False)) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content=None, ++ content_type='text/plain', ++ sender_kw=dict(content=EmptyValue, ++ content_type=EmptyValue, ++ always_hash_content=False)) + +- @raises(MisComputedContentHash) + def test_expected_unhashed_content_with_no_content_type(self): + # This test sets up a scenario where the receiver will receive some + # content but no value for the content_type and no content hash in +@@ -743,11 +739,12 @@ def test_expected_unhashed_content_with_no_content_type(self): + # This is to confirm that the hash is calculated and compared (to the + # hash of mock empty payload, which should fail) when the sender has + # sent unhashed content. +- self.receive(content='some content', +- content_type=None, +- sender_kw=dict(content=EmptyValue, +- content_type=EmptyValue, +- always_hash_content=False)) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content='some content', ++ content_type=None, ++ sender_kw=dict(content=EmptyValue, ++ content_type=EmptyValue, ++ always_hash_content=False)) + + def test_no_content_with_content_type(self): + # This test sets up a scenario where the receiver will receive None for +@@ -760,28 +757,28 @@ def test_no_content_with_content_type(self): + sender_kw=dict(content='', + content_type='text/plain')) + +- @raises(MissingContent) + def test_cannot_receive_empty_content_only(self): + content_type = 'text/plain' +- self.receive(sender_kw=dict(content='', +- content_type=content_type), +- content=EmptyValue, content_type=content_type) ++ with self.assertRaises(MissingContent): ++ self.receive(sender_kw=dict(content='', ++ content_type=content_type), ++ content=EmptyValue, content_type=content_type) + +- @raises(MissingContent) + def test_cannot_receive_empty_content_type_only(self): + content = '' +- self.receive(sender_kw=dict(content=content, +- content_type='text/plain'), +- content=content, content_type=EmptyValue) ++ with self.assertRaises(MissingContent): ++ self.receive(sender_kw=dict(content=content, ++ content_type='text/plain'), ++ content=content, content_type=EmptyValue) + +- @raises(MisComputedContentHash) + def test_receive_wrong_content_type(self): + self.receive(sender_kw=dict(content_type='text/html'), + content_type='text/html') + wrong_sender = self.sender + +- self.receive(content_type='application/json', +- sender=wrong_sender) ++ with self.assertRaises(MisComputedContentHash): ++ self.receive(content_type='application/json', ++ sender=wrong_sender) + + + class TestSendAndReceive(Base): +@@ -879,24 +876,24 @@ def test_bewit_with_ext(self): + expected = '123456\\1356420707\\kscxwNR2tJpP1T1zDLNPbB5UiKIU9tOSJXTUdG7X9h8=\\xandyandz' + assert b64decode(bewit).decode('ascii') == expected + +- @raises(BadHeaderValue) + def test_bewit_with_invalid_ext(self): + res = Resource(url='https://example.com/somewhere/over/the/rainbow', + method='GET', credentials=self.credentials, + timestamp=1356420407 + 300, + nonce='', + ext='xand\\yandz') +- get_bewit(res) ++ with self.assertRaises(BadHeaderValue): ++ get_bewit(res) + +- @raises(BadHeaderValue) + def test_bewit_with_backslashes_in_id(self): + credentials = self.credentials + credentials['id'] = '123\\456' +- res = Resource(url='https://example.com/somewhere/over/the/rainbow', +- method='GET', credentials=self.credentials, +- timestamp=1356420407 + 300, +- nonce='') +- get_bewit(res) ++ with self.assertRaises(BadHeaderValue): ++ res = Resource(url='https://example.com/somewhere/over/the/rainbow', ++ method='GET', credentials=self.credentials, ++ timestamp=1356420407 + 300, ++ nonce='') ++ get_bewit(res) + + def test_bewit_with_port(self): + res = Resource(url='https://example.com:8080/somewhere/over/the/rainbow', +@@ -907,20 +904,20 @@ def test_bewit_with_port(self): + expected = '123456\\1356420707\\hZbJ3P2cKEo4ky0C8jkZAkRyCZueg4WSNbxV7vq3xHU=\\xandyandz' + assert b64decode(bewit).decode('ascii') == expected + +- @raises(ValueError) + def test_bewit_with_nonce(self): + res = Resource(url='https://example.com/somewhere/over/the/rainbow', + method='GET', credentials=self.credentials, + timestamp=1356420407 + 300, + nonce='n1') +- get_bewit(res) ++ with self.assertRaises(ValueError): ++ get_bewit(res) + +- @raises(ValueError) + def test_bewit_invalid_method(self): + res = Resource(url='https://example.com:8080/somewhere/over/the/rainbow', + method='POST', credentials=self.credentials, + timestamp=1356420407 + 300, nonce='') +- get_bewit(res) ++ with self.assertRaises(ValueError): ++ get_bewit(res) + + def test_strip_bewit(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' +@@ -931,10 +928,10 @@ def test_strip_bewit(self): + self.assertEqual(raw_bewit, bewit) + self.assertEqual(stripped_url, "https://example.com/somewhere/over/the/rainbow") + +- @raises(InvalidBewit) + def test_strip_url_without_bewit(self): + url = "https://example.com/somewhere/over/the/rainbow" +- strip_bewit(url) ++ with self.assertRaises(InvalidBewit): ++ strip_bewit(url) + + def test_parse_bewit(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' +@@ -954,23 +951,23 @@ def test_parse_bewit_with_ext(self): + self.assertEqual(bewit.mac, 'IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=') + self.assertEqual(bewit.ext, 'xandyandz') + +- @raises(InvalidBewit) + def test_parse_bewit_with_ext_and_backslashes(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\xand\\yandz' + bewit = urlsafe_b64encode(bewit).decode('ascii') +- parse_bewit(bewit) ++ with self.assertRaises(InvalidBewit): ++ parse_bewit(bewit) + +- @raises(InvalidBewit) + def test_parse_invalid_bewit_with_only_one_part(self): + bewit = b'12345' + bewit = urlsafe_b64encode(bewit).decode('ascii') +- bewit = parse_bewit(bewit) ++ with self.assertRaises(InvalidBewit): ++ bewit = parse_bewit(bewit) + +- @raises(InvalidBewit) + def test_parse_invalid_bewit_with_only_two_parts(self): + bewit = b'1\\2' + bewit = urlsafe_b64encode(bewit).decode('ascii') +- bewit = parse_bewit(bewit) ++ with self.assertRaises(InvalidBewit): ++ bewit = parse_bewit(bewit) + + def test_validate_bewit(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' +@@ -990,7 +987,6 @@ def test_validate_bewit_with_ext(self): + }) + self.assertTrue(check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 10)) + +- @raises(InvalidBewit) + def test_validate_bewit_with_ext_and_backslashes(self): + bewit = b'123456\\1356420707\\b82LLIxG5UDkaChLU953mC+SMrbniV1sb8KiZi9cSsc=\\xand\\yandz' + bewit = urlsafe_b64encode(bewit).decode('ascii') +@@ -998,9 +994,9 @@ def test_validate_bewit_with_ext_and_backslashes(self): + credential_lookup = self.make_credential_lookup({ + self.credentials['id']: self.credentials, + }) +- check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 10) ++ with self.assertRaises(InvalidBewit): ++ check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 10) + +- @raises(TokenExpired) + def test_validate_expired_bewit(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' + bewit = urlsafe_b64encode(bewit).decode('ascii') +@@ -1008,9 +1004,9 @@ def test_validate_expired_bewit(self): + credential_lookup = self.make_credential_lookup({ + self.credentials['id']: self.credentials, + }) +- check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 1000) ++ with self.assertRaises(TokenExpired): ++ check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 1000) + +- @raises(CredentialsLookupError) + def test_validate_bewit_with_unknown_credentials(self): + bewit = b'123456\\1356420707\\IGYmLgIqLrCe8CxvKPs4JlWIA+UjWJJouwgARiVhCAg=\\' + bewit = urlsafe_b64encode(bewit).decode('ascii') +@@ -1018,7 +1014,8 @@ def test_validate_bewit_with_unknown_credentials(self): + credential_lookup = self.make_credential_lookup({ + 'other_id': self.credentials, + }) +- check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 10) ++ with self.assertRaises(CredentialsLookupError): ++ check_bewit(url, credential_lookup=credential_lookup, now=1356420407 + 10) + + + class TestPayloadHash(Base): + +From e5ea6c8b0fad6a4b2e575c4f4ff669b9ac775fad Mon Sep 17 00:00:00 2001 +From: Pyrox +Date: Fri, 2 Aug 2024 15:20:41 -0400 +Subject: [PATCH 3/4] update dependencies + +--- + requirements/dev.txt | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/requirements/dev.txt b/requirements/dev.txt +index 5636a39..4fa2e67 100644 +--- a/requirements/dev.txt ++++ b/requirements/dev.txt +@@ -1,6 +1,6 @@ + # For testing. +-mock >= 3.0.5 +-nose >= 1.3.7 ++mock >= 3.0.5; python_version < '3' ++pytest >=8.0.0 + + # For documentation. + docutils >= 0.15.2 + +From 1788cdfc47273d18c0624bca9bb543f9a88a22e2 Mon Sep 17 00:00:00 2001 +From: Pyrox +Date: Fri, 2 Aug 2024 15:20:47 -0400 +Subject: [PATCH 4/4] update supported python versions + +--- + setup.py | 5 +++++ + tox.ini | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/setup.py b/setup.py +index 122bb36..53617b1 100644 +--- a/setup.py ++++ b/setup.py +@@ -33,6 +33,11 @@ + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ++ 'Programming Language :: Python :: 3.8', ++ 'Programming Language :: Python :: 3.9', ++ 'Programming Language :: Python :: 3.10', ++ 'Programming Language :: Python :: 3.11', ++ 'Programming Language :: Python :: 3.12', + 'Topic :: Internet :: WWW/HTTP', + ], + packages=find_packages(exclude=['tests']), +diff --git a/tox.ini b/tox.ini +index 7357100..3fdeacf 100644 +--- a/tox.ini ++++ b/tox.ini +@@ -2,7 +2,7 @@ + + [tox] + # Also see .travis.yml where this is maintained separately. +-envlist=py27,py34,py35,py36,py37,py38,docs ++envlist=py27,py34,py35,py36,py37,py38,py39,py310,py311,py312,docs + + [base] + deps= +@@ -11,7 +11,7 @@ deps= + [testenv] + deps={[base]deps} + commands= +- nosetests [] ++ pytest mohawk/tests.py + + [testenv:docs] + basepython=python3.7 diff --git a/gnu/packages/python-web.scm b/gnu/packages/python-web.scm index b4c0b560c0d..206a1af9a08 100644 --- a/gnu/packages/python-web.scm +++ b/gnu/packages/python-web.scm @@ -5450,24 +5450,32 @@ protocol, both client and server for Python asyncio module. (license license:asl2.0))) (define-public python-mohawk - (package - (name "python-mohawk") - (version "1.1.0") - (source (origin - (method url-fetch) - (uri (pypi-uri "mohawk" version)) - (sha256 - (base32 - "08wppsv65yd0gdxy5zwq37yp6jmxakfz4a2yx5wwq2d222my786j")))) - (build-system python-build-system) - (native-inputs (list python-mock python-nose)) - (propagated-inputs (list python-six)) - (home-page "https://github.com/kumar303/mohawk") - (synopsis "Library for Hawk HTTP authorization") - (description - "Mohawk is an alternate Python implementation of the Hawk HTTP + (let ((commit "b7899166880e890f01cf2531b5686094ba08df8f") + (revision "0")) + (package + (name "python-mohawk") + (version (git-version "1.1.0" revision commit)) + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/kumar303/mohawk") + (commit commit))) + (file-name (git-file-name name version)) + (sha256 + (base32 "00y9fimcj851rk2770wqk61fac9pnxfnzca4fvsci57zw18i50m6")) + (patches + (search-patches "python-mohawk-pytest.patch")))) + (build-system pyproject-build-system) + (arguments + (list #:test-flags #~(list "mohawk/tests.py"))) + (native-inputs (list python-pytest python-setuptools-next)) + (home-page "https://github.com/kumar303/mohawk") + (synopsis "Library for Hawk HTTP authorization") + (description + "Mohawk is an alternate Python implementation of the Hawk HTTP authorization scheme.") - (license license:bsd-3))) + (license license:bsd-3)))) (define-public python-msal (package