From 945e8e670d0cd9d599fc15b736ceb9769752f49a Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Sun, 15 Oct 2023 17:26:44 +0200 Subject: [PATCH 1/4] remove six dependecy --- mastodon/streaming.py | 36 +++++++----------------------------- pyproject.toml | 1 - tests/test_streaming.py | 5 ++--- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/mastodon/streaming.py b/mastodon/streaming.py index c9cf2e3..c2dc7f6 100644 --- a/mastodon/streaming.py +++ b/mastodon/streaming.py @@ -4,7 +4,6 @@ https://github.com/mastodon/documentation/blob/master/content/en/methods/timelin """ import json -import six try: from inspect import signature except: @@ -131,10 +130,7 @@ class StreamListener(object): exception = MastodonMalformedEventError( "Malformed UTF-8") self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err if line == '': self._dispatch(event) event = {} @@ -146,26 +142,17 @@ class StreamListener(object): except ChunkedEncodingError as err: exception = MastodonNetworkError("Server ceased communication.") self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err except ReadTimeout as err: exception = MastodonReadTimeout( "Timed out while reading from server."), self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err except ConnectionError as err: exception = MastodonNetworkError( "Requests reports connection error."), self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err def _parse_line(self, line, event): if line.startswith(':'): @@ -200,19 +187,13 @@ class StreamListener(object): exception = MastodonMalformedEventError( 'Missing field', err.args[0], event) self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err except ValueError as err: # py2: plain ValueError # py3: json.JSONDecodeError, a subclass of ValueError exception = MastodonMalformedEventError('Bad JSON', data) self.on_abort(exception) - six.raise_from( - exception, - err - ) + raise exception from err # New mastodon API also supports event names with dots, # specifically, status_update. @@ -287,10 +268,7 @@ class CallbackStreamListener(StreamListener): if self.local_update_handler is not None and not "@" in status["account"]["acct"]: self.local_update_handler(status) except Exception as err: - six.raise_from( - MastodonMalformedEventError('received bad update', status), - err - ) + raise MastodonMalformedEventError('received bad update', status) from err def on_delete(self, deleted_id): if self.delete_handler is not None: diff --git a/pyproject.toml b/pyproject.toml index 47df21c..5d570c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,6 @@ classifiers = [ dependencies = [ 'requests>=2.4.2', 'python-dateutil', - 'six', 'python-magic-bin ; platform_system=="Windows"', 'python-magic ; platform_system!="Windows"', 'decorator>=4.0.0', diff --git a/tests/test_streaming.py b/tests/test_streaming.py index 0295d49..9478824 100644 --- a/tests/test_streaming.py +++ b/tests/test_streaming.py @@ -1,4 +1,3 @@ -import six import pytest import itertools from mastodon.streaming import StreamListener, CallbackStreamListener @@ -98,7 +97,7 @@ class Listener(StreamListener): class MockResponse(): def __init__(self, data): self.data = data - + def iter_content(self, chunk_size): for line in self.data: for byte in line: @@ -106,7 +105,7 @@ class Listener(StreamListener): bytearr.append(byte) yield(bytearr) yield(b'\n') - return self.handle_stream(MockResponse(map(six.b, lines))) + return self.handle_stream(MockResponse(map(bytes, lines))) def test_heartbeat(): From 0f89d178129ce14ef1152c3ec38d7deb929423e1 Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Sun, 15 Oct 2023 17:37:50 +0200 Subject: [PATCH 2/4] temporary: try to make CI happy --- tests/test_streaming.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_streaming.py b/tests/test_streaming.py index 9478824..7f90a78 100644 --- a/tests/test_streaming.py +++ b/tests/test_streaming.py @@ -94,6 +94,9 @@ class Listener(StreamListener): def handle_stream_(self, lines): """Test helper to avoid littering all tests with six.b().""" + def six_b(s): + return s.encode("latin-1") + class MockResponse(): def __init__(self, data): self.data = data @@ -105,7 +108,7 @@ class Listener(StreamListener): bytearr.append(byte) yield(bytearr) yield(b'\n') - return self.handle_stream(MockResponse(map(bytes, lines))) + return self.handle_stream(MockResponse(map(six_b, lines))) def test_heartbeat(): From 690ece95d9337c5ddc1a3a7d381c6a01fcf454fc Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Sun, 15 Oct 2023 17:48:42 +0200 Subject: [PATCH 3/4] drop local compat helper too --- tests/test_streaming.py | 142 ++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 80 deletions(-) diff --git a/tests/test_streaming.py b/tests/test_streaming.py index 7f90a78..85926eb 100644 --- a/tests/test_streaming.py +++ b/tests/test_streaming.py @@ -92,57 +92,39 @@ class Listener(StreamListener): def handle_heartbeat(self): self.heartbeats += 1 - def handle_stream_(self, lines): - """Test helper to avoid littering all tests with six.b().""" - def six_b(s): - return s.encode("latin-1") - - class MockResponse(): - def __init__(self, data): - self.data = data - - def iter_content(self, chunk_size): - for line in self.data: - for byte in line: - bytearr = bytearray() - bytearr.append(byte) - yield(bytearr) - yield(b'\n') - return self.handle_stream(MockResponse(map(six_b, lines))) - def test_heartbeat(): listener = Listener() - listener.handle_stream_([':one', ':two']) + listener.handle_stream([b':one', b':two']) assert listener.heartbeats == 2 def test_status(): listener = Listener() - listener.handle_stream_([ - 'event: update', - 'data: {"foo": "bar"}', - '', + listener.handle_stream([ + b'event: update', + b'data: {"foo": "bar"}', + b'', ]) assert listener.updates == [{"foo": "bar"}] def test_notification(): listener = Listener() - listener.handle_stream_([ - 'event: notification', - 'data: {"foo": "bar"}', - '', + listener.handle_stream([ + b'event: notification', + b'data: {"foo": "bar"}', + b'', ]) assert listener.notifications == [{"foo": "bar"}] def test_delete(): listener = Listener() - listener.handle_stream_([ - 'event: delete', - 'data: 123', - '', + listener.handle_stream([ + b'event: delete', + b'data: 123', + b'', ]) assert listener.deletes == ["123"] @@ -157,11 +139,11 @@ def test_delete(): def test_many(events): listener = Listener() stream = [ - line + line.encode('latin1') for event in events for line in event ] - listener.handle_stream_(stream) + listener.handle_stream(stream) assert listener.updates == [{"foo": "bar"}] assert listener.notifications == [{"foo": "bar"}] assert listener.deletes == ["123"] @@ -171,10 +153,10 @@ def test_many(events): def test_unknown_event(): """Be tolerant of new event types""" listener = Listener() - listener.handle_stream_([ - 'event: blahblah', - 'data: {}', - '', + listener.handle_stream([ + b'event: blahblah', + b'data: {}', + b'', ]) assert listener.bla_called is True assert listener.updates == [] @@ -187,10 +169,10 @@ def test_unknown_handled_event(): listener = Listener() listener.on_unknown_event = lambda name, payload: None - listener.handle_stream_([ - 'event: complete.new.event', - 'data: {"k": "v"}', - '', + listener.handle_stream([ + b'event: complete.new.event', + b'data: {"k": "v"}', + b'', ]) assert listener.updates == [] @@ -201,10 +183,10 @@ def test_unknown_handled_event(): def test_dotted_unknown_event(): """Be tolerant of new event types with dots in the event-name""" listener = Listener() - listener.handle_stream_([ - 'event: do.something', - 'data: {}', - '', + listener.handle_stream([ + b'event: do.something', + b'data: {}', + b'', ]) assert listener.do_something_called is True assert listener.updates == [] @@ -216,18 +198,18 @@ def test_invalid_json(): """But not too tolerant""" listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream_([ - 'event: blahblah', - 'data: {kjaslkdjalskdjasd asdkjhak ajdasldasd}', - '', + listener.handle_stream([ + b'event: blahblah', + b'data: {kjaslkdjalskdjasd asdkjhak ajdasldasd}', + b'', ]) def test_missing_event_name(): listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream_([ - 'data: {}', - '', + listener.handle_stream([ + b'data: {}', + b'', ]) assert listener.updates == [] @@ -239,9 +221,9 @@ def test_missing_event_name(): def test_missing_data(): listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream_([ - 'event: update', - '', + listener.handle_stream([ + b'event: update', + b'', ]) assert listener.updates == [] @@ -252,10 +234,10 @@ def test_missing_data(): def test_sse_order_doesnt_matter(): listener = Listener() - listener.handle_stream_([ - 'data: {"foo": "bar"}', - 'event: update', - '', + listener.handle_stream([ + b'data: {"foo": "bar"}', + b'event: update', + b'', ]) assert listener.updates == [{"foo": "bar"}] @@ -267,13 +249,13 @@ def test_extra_keys_ignored(): and alleges that "All other field names are ignored". """ listener = Listener() - listener.handle_stream_([ - 'event: update', - 'data: {"foo": "bar"}', - 'id: 123', - 'retry: 456', - 'ignoreme: blah blah blah', - '', + listener.handle_stream([ + b'event: update', + b'data: {"foo": "bar"}', + b'id: 123', + b'retry: 456', + b'ignoreme: blah blah blah', + b'', ]) assert listener.updates == [{"foo": "bar"}] @@ -281,10 +263,10 @@ def test_extra_keys_ignored(): def test_valid_utf8(): """Snowman Cat Face With Tears Of Joy""" listener = Listener() - listener.handle_stream_([ - 'event: update', - 'data: {"foo": "\xE2\x98\x83\xF0\x9F\x98\xB9"}', - '', + listener.handle_stream([ + b'event: update', + b'data: {"foo": "\xE2\x98\x83\xF0\x9F\x98\xB9"}', + b'', ]) assert listener.updates == [{"foo": u"\u2603\U0001F639"}] @@ -293,10 +275,10 @@ def test_invalid_utf8(): """Cat Face With Tears O""" listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream_([ - 'event: update', - 'data: {"foo": "\xF0\x9F\x98"}', - '', + listener.handle_stream([ + b'event: update', + b'data: {"foo": "\xF0\x9F\x98"}', + b'', ]) @@ -309,12 +291,12 @@ def test_multiline_payload(): so let's handle this case. """ listener = Listener() - listener.handle_stream_([ - 'event: update', - 'data: {"foo":', - 'data: "bar"', - 'data: }', - '', + listener.handle_stream([ + b'event: update', + b'data: {"foo":', + b'data: "bar"', + b'data: }', + b'', ]) assert listener.updates == [{"foo": "bar"}] From 1c891a445f471545e61df17697b5c13140d6244c Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Sun, 15 Oct 2023 17:58:49 +0200 Subject: [PATCH 4/4] Revert "drop local compat helper too" This reverts commit 690ece95d9337c5ddc1a3a7d381c6a01fcf454fc. --- tests/test_streaming.py | 142 ++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 62 deletions(-) diff --git a/tests/test_streaming.py b/tests/test_streaming.py index 85926eb..7f90a78 100644 --- a/tests/test_streaming.py +++ b/tests/test_streaming.py @@ -92,39 +92,57 @@ class Listener(StreamListener): def handle_heartbeat(self): self.heartbeats += 1 + def handle_stream_(self, lines): + """Test helper to avoid littering all tests with six.b().""" + def six_b(s): + return s.encode("latin-1") + + class MockResponse(): + def __init__(self, data): + self.data = data + + def iter_content(self, chunk_size): + for line in self.data: + for byte in line: + bytearr = bytearray() + bytearr.append(byte) + yield(bytearr) + yield(b'\n') + return self.handle_stream(MockResponse(map(six_b, lines))) + def test_heartbeat(): listener = Listener() - listener.handle_stream([b':one', b':two']) + listener.handle_stream_([':one', ':two']) assert listener.heartbeats == 2 def test_status(): listener = Listener() - listener.handle_stream([ - b'event: update', - b'data: {"foo": "bar"}', - b'', + listener.handle_stream_([ + 'event: update', + 'data: {"foo": "bar"}', + '', ]) assert listener.updates == [{"foo": "bar"}] def test_notification(): listener = Listener() - listener.handle_stream([ - b'event: notification', - b'data: {"foo": "bar"}', - b'', + listener.handle_stream_([ + 'event: notification', + 'data: {"foo": "bar"}', + '', ]) assert listener.notifications == [{"foo": "bar"}] def test_delete(): listener = Listener() - listener.handle_stream([ - b'event: delete', - b'data: 123', - b'', + listener.handle_stream_([ + 'event: delete', + 'data: 123', + '', ]) assert listener.deletes == ["123"] @@ -139,11 +157,11 @@ def test_delete(): def test_many(events): listener = Listener() stream = [ - line.encode('latin1') + line for event in events for line in event ] - listener.handle_stream(stream) + listener.handle_stream_(stream) assert listener.updates == [{"foo": "bar"}] assert listener.notifications == [{"foo": "bar"}] assert listener.deletes == ["123"] @@ -153,10 +171,10 @@ def test_many(events): def test_unknown_event(): """Be tolerant of new event types""" listener = Listener() - listener.handle_stream([ - b'event: blahblah', - b'data: {}', - b'', + listener.handle_stream_([ + 'event: blahblah', + 'data: {}', + '', ]) assert listener.bla_called is True assert listener.updates == [] @@ -169,10 +187,10 @@ def test_unknown_handled_event(): listener = Listener() listener.on_unknown_event = lambda name, payload: None - listener.handle_stream([ - b'event: complete.new.event', - b'data: {"k": "v"}', - b'', + listener.handle_stream_([ + 'event: complete.new.event', + 'data: {"k": "v"}', + '', ]) assert listener.updates == [] @@ -183,10 +201,10 @@ def test_unknown_handled_event(): def test_dotted_unknown_event(): """Be tolerant of new event types with dots in the event-name""" listener = Listener() - listener.handle_stream([ - b'event: do.something', - b'data: {}', - b'', + listener.handle_stream_([ + 'event: do.something', + 'data: {}', + '', ]) assert listener.do_something_called is True assert listener.updates == [] @@ -198,18 +216,18 @@ def test_invalid_json(): """But not too tolerant""" listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream([ - b'event: blahblah', - b'data: {kjaslkdjalskdjasd asdkjhak ajdasldasd}', - b'', + listener.handle_stream_([ + 'event: blahblah', + 'data: {kjaslkdjalskdjasd asdkjhak ajdasldasd}', + '', ]) def test_missing_event_name(): listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream([ - b'data: {}', - b'', + listener.handle_stream_([ + 'data: {}', + '', ]) assert listener.updates == [] @@ -221,9 +239,9 @@ def test_missing_event_name(): def test_missing_data(): listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream([ - b'event: update', - b'', + listener.handle_stream_([ + 'event: update', + '', ]) assert listener.updates == [] @@ -234,10 +252,10 @@ def test_missing_data(): def test_sse_order_doesnt_matter(): listener = Listener() - listener.handle_stream([ - b'data: {"foo": "bar"}', - b'event: update', - b'', + listener.handle_stream_([ + 'data: {"foo": "bar"}', + 'event: update', + '', ]) assert listener.updates == [{"foo": "bar"}] @@ -249,13 +267,13 @@ def test_extra_keys_ignored(): and alleges that "All other field names are ignored". """ listener = Listener() - listener.handle_stream([ - b'event: update', - b'data: {"foo": "bar"}', - b'id: 123', - b'retry: 456', - b'ignoreme: blah blah blah', - b'', + listener.handle_stream_([ + 'event: update', + 'data: {"foo": "bar"}', + 'id: 123', + 'retry: 456', + 'ignoreme: blah blah blah', + '', ]) assert listener.updates == [{"foo": "bar"}] @@ -263,10 +281,10 @@ def test_extra_keys_ignored(): def test_valid_utf8(): """Snowman Cat Face With Tears Of Joy""" listener = Listener() - listener.handle_stream([ - b'event: update', - b'data: {"foo": "\xE2\x98\x83\xF0\x9F\x98\xB9"}', - b'', + listener.handle_stream_([ + 'event: update', + 'data: {"foo": "\xE2\x98\x83\xF0\x9F\x98\xB9"}', + '', ]) assert listener.updates == [{"foo": u"\u2603\U0001F639"}] @@ -275,10 +293,10 @@ def test_invalid_utf8(): """Cat Face With Tears O""" listener = Listener() with pytest.raises(MastodonMalformedEventError): - listener.handle_stream([ - b'event: update', - b'data: {"foo": "\xF0\x9F\x98"}', - b'', + listener.handle_stream_([ + 'event: update', + 'data: {"foo": "\xF0\x9F\x98"}', + '', ]) @@ -291,12 +309,12 @@ def test_multiline_payload(): so let's handle this case. """ listener = Listener() - listener.handle_stream([ - b'event: update', - b'data: {"foo":', - b'data: "bar"', - b'data: }', - b'', + listener.handle_stream_([ + 'event: update', + 'data: {"foo":', + 'data: "bar"', + 'data: }', + '', ]) assert listener.updates == [{"foo": "bar"}]