Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-mocket for openSUSE:Factory checked in at 2023-02-28 12:48:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-mocket (Old) and /work/SRC/openSUSE:Factory/.python-mocket.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-mocket" Tue Feb 28 12:48:00 2023 rev:26 rq:1067850 version:3.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-mocket/python-mocket.changes 2023-02-18 17:10:17.554700699 +0100 +++ /work/SRC/openSUSE:Factory/.python-mocket.new.31432/python-mocket.changes 2023-02-28 12:48:23.364381922 +0100 @@ -1,0 +2,16 @@ +Sun Feb 19 21:05:20 UTC 2023 - Sebastian Wagner <se...@sebix.at> + +- Update to version 3.11: + - Migrating the HTTP[S] mock from relying on http-parser to httptools. + - Never discovered the root cause for the failing tests with aiohttp/Python 3.11 (first time ever I added @pytest.mark.xfail to a few tests). Same test works with httpx, so I suspect it's related to a client issue. I'll probably migrate to httpx as the reference client for testing async/await code. +- remove patches merged upstream: + 0007-Switching-to-httptools.parser.HttpRequestParser.patch + 0008-Disabling-tests-for-pook-when-testing-Python-3.11.patch + 0009-Removing-DeprecationWarning-all-over-the-place.patch + 0010-Python-3.11-needs-an-async-decorator.patch + 0012-Removing-async-timeout-dependency.patch + 0013-Refactoring-using-event_loop-fixture.patch + 0014-Refactoring-using-tempfile-as-a-context-manager.patch + 0015-Skip-those-tests-and-see-what-happens-to-the-rest.patch + +------------------------------------------------------------------- Old: ---- 0007-Switching-to-httptools.parser.HttpRequestParser.patch 0008-Disabling-tests-for-pook-when-testing-Python-3.11.patch 0009-Removing-DeprecationWarning-all-over-the-place.patch 0010-Python-3.11-needs-an-async-decorator.patch 0012-Removing-async-timeout-dependency.patch 0013-Refactoring-using-event_loop-fixture.patch 0014-Refactoring-using-tempfile-as-a-context-manager.patch 0015-Skip-those-tests-and-see-what-happens-to-the-rest.patch mocket-3.10.9.tar.gz New: ---- mocket-3.11.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-mocket.spec ++++++ --- /var/tmp/diff_new_pack.mJZCVC/_old 2023-02-28 12:48:24.020386183 +0100 +++ /var/tmp/diff_new_pack.mJZCVC/_new 2023-02-28 12:48:24.028386235 +0100 @@ -27,21 +27,12 @@ %define skip_python2 1 Name: python-mocket%{psuffix} -Version: 3.10.9 +Version: 3.11.0 Release: 0 Summary: Python socket mock framework License: BSD-3-Clause URL: https://github.com/mindflayer/python-mocket Source0: https://files.pythonhosted.org/packages/source/m/mocket/mocket-%{version}.tar.gz -# PATCH-FIX-UPSTREAM: taken from https://github.com/mindflayer/python-mocket/pull/181 -Patch1: 0007-Switching-to-httptools.parser.HttpRequestParser.patch -Patch2: 0008-Disabling-tests-for-pook-when-testing-Python-3.11.patch -Patch3: 0009-Removing-DeprecationWarning-all-over-the-place.patch -Patch4: 0010-Python-3.11-needs-an-async-decorator.patch -Patch5: 0012-Removing-async-timeout-dependency.patch -Patch6: 0013-Refactoring-using-event_loop-fixture.patch -Patch7: 0014-Refactoring-using-tempfile-as-a-context-manager.patch -Patch8: 0015-Skip-those-tests-and-see-what-happens-to-the-rest.patch BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -109,7 +100,7 @@ donttest="$donttest or test_truesendall_with_dump_from_recording" %endif # these fail after the python 3.11 patches -donttest="$donttest or test_http_session or test_https_session or test_httprettish_session" +#donttest="$donttest or test_http_session or test_https_session or test_httprettish_session" %pytest -rfEs -k "not ($donttest)" ${pytest_$python_ignore} %endif ++++++ mocket-3.10.9.tar.gz -> mocket-3.11.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/PKG-INFO new/mocket-3.11.0/PKG-INFO --- old/mocket-3.10.9/PKG-INFO 2022-12-03 23:22:43.329145000 +0100 +++ new/mocket-3.11.0/PKG-INFO 2023-02-19 16:56:36.339939000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: mocket -Version: 3.10.9 +Version: 3.11.0 Summary: Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support Home-page: https://github.com/mindflayer/python-mocket Author: Giorgio Salluzzo @@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development @@ -259,7 +260,6 @@ import aiohttp import asyncio - import async_timeout from unittest import TestCase from mocket.plugins.httpretty import httpretty, httprettified @@ -276,13 +276,14 @@ ) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 200 - assert await get_response.text() == '{"origin": "127.0.0.1"}' + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 200 + assert await get_response.text() == '{"origin": "127.0.0.1"}' - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.set_debug(True) loop.run_until_complete(main(loop)) @@ -305,18 +306,18 @@ Entry.single_register(Entry.POST, url, body=body*2, status=201) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.run_until_complete(main(loop)) # or again with a unittest.IsolatedAsyncioTestCase @@ -330,18 +331,18 @@ Entry.single_register(Entry.GET, url, body=body, status=404) Entry.single_register(Entry.POST, url, body=body * 2, status=201) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - assert Mocket.last_request().method == 'POST' - assert Mocket.last_request().body == body * 6 + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + assert Mocket.last_request().method == 'POST' + assert Mocket.last_request().body == body * 6 Works well with others diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/README.rst new/mocket-3.11.0/README.rst --- old/mocket-3.10.9/README.rst 2022-12-03 23:22:22.000000000 +0100 +++ new/mocket-3.11.0/README.rst 2023-02-19 16:55:48.000000000 +0100 @@ -231,7 +231,6 @@ import aiohttp import asyncio - import async_timeout from unittest import TestCase from mocket.plugins.httpretty import httpretty, httprettified @@ -248,13 +247,14 @@ ) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 200 - assert await get_response.text() == '{"origin": "127.0.0.1"}' + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 200 + assert await get_response.text() == '{"origin": "127.0.0.1"}' - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.set_debug(True) loop.run_until_complete(main(loop)) @@ -277,18 +277,18 @@ Entry.single_register(Entry.POST, url, body=body*2, status=201) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.run_until_complete(main(loop)) # or again with a unittest.IsolatedAsyncioTestCase @@ -302,18 +302,18 @@ Entry.single_register(Entry.GET, url, body=body, status=404) Entry.single_register(Entry.POST, url, body=body * 2, status=201) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - assert Mocket.last_request().method == 'POST' - assert Mocket.last_request().body == body * 6 + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + assert Mocket.last_request().method == 'POST' + assert Mocket.last_request().body == body * 6 Works well with others diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket/__init__.py new/mocket-3.11.0/mocket/__init__.py --- old/mocket-3.10.9/mocket/__init__.py 2022-12-03 23:22:22.000000000 +0100 +++ new/mocket-3.11.0/mocket/__init__.py 2023-02-19 16:55:48.000000000 +0100 @@ -3,4 +3,4 @@ __all__ = ("async_mocketize", "mocketize", "Mocket", "MocketEntry", "Mocketizer") -__version__ = "3.10.9" +__version__ = "3.11.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket/mockhttp.py new/mocket-3.11.0/mocket/mockhttp.py --- old/mocket-3.10.9/mocket/mockhttp.py 2021-12-01 19:57:28.000000000 +0100 +++ new/mocket-3.11.0/mocket/mockhttp.py 2023-02-19 16:55:48.000000000 +0100 @@ -3,13 +3,10 @@ from http.server import BaseHTTPRequestHandler from urllib.parse import parse_qs, unquote, urlsplit -from .compat import decode_from_bytes, do_the_magic, encode_to_bytes -from .mocket import Mocket, MocketEntry +from httptools.parser import HttpRequestParser -try: - from http_parser.parser import HttpParser -except ImportError: - from http_parser.pyparser import HttpParser +from .compat import ENCODING, decode_from_bytes, do_the_magic, encode_to_bytes +from .mocket import Mocket, MocketEntry try: import magic @@ -21,31 +18,59 @@ CRLF = "\r\n" +class Protocol: + def __init__(self): + self.url = None + self.body = None + self.headers = {} + + def on_header(self, name: bytes, value: bytes): + self.headers[name.decode("ascii")] = value.decode("ascii") + + def on_body(self, body: bytes): + try: + self.body = body.decode(ENCODING) + except UnicodeDecodeError: + self.body = body + + def on_url(self, url: bytes): + self.url = url.decode("ascii") + + class Request: - parser = None - _body = None + _protocol = None + _parser = None def __init__(self, data): - self.parser = HttpParser() - self.parser.execute(data, len(data)) - - self.method = self.parser.get_method() - self.path = self.parser.get_path() - self.headers = self.parser.get_headers() - self.querystring = parse_qs( - unquote(self.parser.get_query_string()), keep_blank_values=True - ) - if self.querystring: - self.path += "?{}".format(self.parser.get_query_string()) + self._protocol = Protocol() + self._parser = HttpRequestParser(self._protocol) + self.add_data(data) def add_data(self, data): - self.parser.execute(data, len(data)) + self._parser.feed_data(data) + + @property + def method(self): + return self._parser.get_method().decode("ascii") + + @property + def path(self): + return self._protocol.url + + @property + def headers(self): + return self._protocol.headers + + @property + def querystring(self): + parts = self._protocol.url.split("?", 1) + if len(parts) == 2: + return parse_qs(unquote(parts[1]), keep_blank_values=True) + return {} @property def body(self): - if self._body is None: - self._body = decode_from_bytes(self.parser.recv_body()) - return self._body + return self._protocol.body def __str__(self): return "{} - {} - {}".format(self.method, self.path, self.headers) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket/plugins/httpretty/__init__.py new/mocket-3.11.0/mocket/plugins/httpretty/__init__.py --- old/mocket-3.10.9/mocket/plugins/httpretty/__init__.py 2022-01-08 17:50:17.000000000 +0100 +++ new/mocket-3.11.0/mocket/plugins/httpretty/__init__.py 2023-02-19 16:55:48.000000000 +0100 @@ -1,6 +1,6 @@ from mocket import Mocket, mocketize from mocket.async_mocket import async_mocketize -from mocket.compat import byte_type, text_type +from mocket.compat import ENCODING, byte_type, text_type from mocket.mockhttp import Entry as MocketHttpEntry from mocket.mockhttp import Request as MocketHttpRequest from mocket.mockhttp import Response as MocketHttpResponse @@ -13,9 +13,11 @@ class Request(MocketHttpRequest): @property def body(self): - if self._body is None: - self._body = self.parser.recv_body() - return self._body + return super().body.encode(ENCODING) + + @property + def headers(self): + return httprettifier_headers(super().headers) class Response(MocketHttpResponse): @@ -116,6 +118,7 @@ __all__ = ( "HTTPretty", + "httpretty", "activate", "async_httprettified", "httprettified", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket/plugins/pook_mock_engine.py new/mocket-3.11.0/mocket/plugins/pook_mock_engine.py --- old/mocket-3.10.9/mocket/plugins/pook_mock_engine.py 2022-05-18 14:31:33.000000000 +0200 +++ new/mocket-3.11.0/mocket/plugins/pook_mock_engine.py 2023-02-19 16:55:48.000000000 +0100 @@ -1,71 +1,76 @@ -from pook.engine import MockEngine -from pook.interceptors.base import BaseInterceptor +import platform -from mocket.mocket import Mocket -from mocket.mockhttp import Entry, Response - - -class MocketPookEntry(Entry): - pook_request = None - pook_engine = None - - def can_handle(self, data): - can_handle = super(MocketPookEntry, self).can_handle(data) - - if can_handle: - self.pook_engine.match(self.pook_request) - return can_handle - - @classmethod - def single_register(cls, method, uri, body='', status=200, headers=None, match_querystring=True): - entry = cls( - uri, method, Response( - body=body, status=status, headers=headers - ), match_querystring=match_querystring - ) - Mocket.register(entry) - return entry - - -class MocketInterceptor(BaseInterceptor): - @staticmethod - def activate(): - Mocket.disable() - Mocket.enable() - - @staticmethod - def disable(): - Mocket.disable() - - -class MocketEngine(MockEngine): - - def __init__(self, engine): - def mocket_mock_fun(*args, **kwargs): - mock = self.pook_mock_fun(*args, **kwargs) - - request = mock._request - method = request.method - url = request.rawurl - - response = mock._response - body = response._body - status = response._status - headers = response._headers - - entry = MocketPookEntry.single_register(method, url, body, status, headers) - entry.pook_engine = self.engine - entry.pook_request = request - - return mock - - # Store plugins engine - self.engine = engine - # Store HTTP client interceptors - self.interceptors = [] - # Self-register MocketInterceptor - self.add_interceptor(MocketInterceptor) - - # mocking pook.mock() - self.pook_mock_fun = self.engine.mock - self.engine.mock = mocket_mock_fun +if not platform.python_version().startswith("3.11."): + # it looks like `pook` is not compatible with Python 3.11 + from pook.engine import MockEngine + from pook.interceptors.base import BaseInterceptor + + from mocket.mocket import Mocket + from mocket.mockhttp import Entry, Response + + class MocketPookEntry(Entry): + pook_request = None + pook_engine = None + + def can_handle(self, data): + can_handle = super(MocketPookEntry, self).can_handle(data) + + if can_handle: + self.pook_engine.match(self.pook_request) + return can_handle + + @classmethod + def single_register( + cls, method, uri, body="", status=200, headers=None, match_querystring=True + ): + entry = cls( + uri, + method, + Response(body=body, status=status, headers=headers), + match_querystring=match_querystring, + ) + Mocket.register(entry) + return entry + + class MocketInterceptor(BaseInterceptor): + @staticmethod + def activate(): + Mocket.disable() + Mocket.enable() + + @staticmethod + def disable(): + Mocket.disable() + + class MocketEngine(MockEngine): + def __init__(self, engine): + def mocket_mock_fun(*args, **kwargs): + mock = self.pook_mock_fun(*args, **kwargs) + + request = mock._request + method = request.method + url = request.rawurl + + response = mock._response + body = response._body + status = response._status + headers = response._headers + + entry = MocketPookEntry.single_register( + method, url, body, status, headers + ) + entry.pook_engine = self.engine + entry.pook_request = request + + return mock + + # Store plugins engine + self.engine = engine + # Store HTTP client interceptors + self.interceptors = [] + # Self-register MocketInterceptor + self.add_interceptor(MocketInterceptor) + + # mocking pook.mock() + self.pook_mock_fun = self.engine.mock + self.engine.mock = mocket_mock_fun diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket.egg-info/PKG-INFO new/mocket-3.11.0/mocket.egg-info/PKG-INFO --- old/mocket-3.10.9/mocket.egg-info/PKG-INFO 2022-12-03 23:22:43.000000000 +0100 +++ new/mocket-3.11.0/mocket.egg-info/PKG-INFO 2023-02-19 16:56:36.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: mocket -Version: 3.10.9 +Version: 3.11.0 Summary: Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support Home-page: https://github.com/mindflayer/python-mocket Author: Giorgio Salluzzo @@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Software Development @@ -259,7 +260,6 @@ import aiohttp import asyncio - import async_timeout from unittest import TestCase from mocket.plugins.httpretty import httpretty, httprettified @@ -276,13 +276,14 @@ ) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 200 - assert await get_response.text() == '{"origin": "127.0.0.1"}' + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 200 + assert await get_response.text() == '{"origin": "127.0.0.1"}' - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.set_debug(True) loop.run_until_complete(main(loop)) @@ -305,18 +306,18 @@ Entry.single_register(Entry.POST, url, body=body*2, status=201) async def main(l): - async with aiohttp.ClientSession(loop=l) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 + async with aiohttp.ClientSession( + loop=l, timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() loop.run_until_complete(main(loop)) # or again with a unittest.IsolatedAsyncioTestCase @@ -330,18 +331,18 @@ Entry.single_register(Entry.GET, url, body=body, status=404) Entry.single_register(Entry.POST, url, body=body * 2, status=201) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - assert Mocket.last_request().method == 'POST' - assert Mocket.last_request().body == body * 6 + async with aiohttp.ClientSession( + timeout=aiohttp.ClientTimeout(total=3) + ) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + assert Mocket.last_request().method == 'POST' + assert Mocket.last_request().body == body * 6 Works well with others diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/mocket.egg-info/requires.txt new/mocket-3.11.0/mocket.egg-info/requires.txt --- old/mocket-3.10.9/mocket.egg-info/requires.txt 2022-12-03 23:22:43.000000000 +0100 +++ new/mocket-3.11.0/mocket.egg-info/requires.txt 2023-02-19 16:56:36.000000000 +0100 @@ -1,7 +1,7 @@ python-magic>=0.4.5 decorator>=4.0.0 urllib3>=1.25.3 -http-parser>=0.9.0 +httptools [dev] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/requirements.txt new/mocket-3.11.0/requirements.txt --- old/mocket-3.10.9/requirements.txt 2022-12-03 23:22:40.000000000 +0100 +++ new/mocket-3.11.0/requirements.txt 2023-02-19 16:56:32.000000000 +0100 @@ -1,4 +1,4 @@ python-magic>=0.4.5 decorator>=4.0.0 urllib3>=1.25.3 -http-parser>=0.9.0 +httptools diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/setup.py new/mocket-3.11.0/setup.py --- old/mocket-3.10.9/setup.py 2022-08-11 14:47:42.000000000 +0200 +++ new/mocket-3.11.0/setup.py 2023-02-19 16:55:48.000000000 +0100 @@ -57,6 +57,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/main/test_http.py new/mocket-3.11.0/tests/main/test_http.py --- old/mocket-3.10.9/tests/main/test_http.py 2022-05-17 21:03:18.000000000 +0200 +++ new/mocket-3.11.0/tests/main/test_http.py 2023-02-19 16:55:48.000000000 +0100 @@ -13,17 +13,15 @@ import pytest import requests -from mocket import Mocket, mocketize +from mocket import Mocket, Mocketizer, mocketize from mocket.mockhttp import Entry, Response -recording_directory = tempfile.mkdtemp() - class HttpTestCase(TestCase): def assertEqualHeaders(self, first, second, msg=None): first = {k.lower(): v for k, v in first.items()} second = {k.lower(): v for k, v in second.items()} - self.assertEqual(first, second, msg) + self.assertDictEqual(first, second, msg) @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') @@ -36,57 +34,63 @@ resp = requests.get(url) self.assertEqual(resp.status_code, 200) - @mocketize(truesocket_recording_dir=recording_directory) def test_truesendall_with_recording(self): - url = "http://httpbin.org/ip" - - urlopen(url) - requests.get(url) - resp = urlopen(url) - self.assertEqual(resp.code, 200) - resp = requests.get(url) - self.assertEqual(resp.status_code, 200) - assert "origin" in resp.json() - - dump_filename = os.path.join( - Mocket.get_truesocket_recording_dir(), Mocket.get_namespace() + ".json" - ) - with io.open(dump_filename) as f: - responses = json.load(f) + with tempfile.TemporaryDirectory() as temp_dir: + with Mocketizer(truesocket_recording_dir=temp_dir): + url = "http://httpbin.org/ip" + + urlopen(url) + requests.get(url) + resp = urlopen(url) + self.assertEqual(resp.code, 200) + resp = requests.get(url) + self.assertEqual(resp.status_code, 200) + assert "origin" in resp.json() + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + ".json", + ) + with io.open(dump_filename) as f: + responses = json.load(f) - self.assertEqual(len(responses["httpbin.org"]["80"].keys()), 2) + self.assertEqual(len(responses["httpbin.org"]["80"].keys()), 2) - @mocketize(truesocket_recording_dir=recording_directory) def test_truesendall_with_gzip_recording(self): - url = "http://httpbin.org/gzip" + with tempfile.TemporaryDirectory() as temp_dir: + with Mocketizer(truesocket_recording_dir=temp_dir): + url = "http://httpbin.org/gzip" + + requests.get(url) + resp = requests.get(url) + self.assertEqual(resp.status_code, 200) + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + ".json", + ) + with io.open(dump_filename) as f: + responses = json.load(f) - requests.get(url) - resp = requests.get(url) - self.assertEqual(resp.status_code, 200) - - dump_filename = os.path.join( - Mocket.get_truesocket_recording_dir(), Mocket.get_namespace() + ".json" - ) - with io.open(dump_filename) as f: - responses = json.load(f) - - assert len(responses["httpbin.org"]["80"].keys()) == 1 + assert len(responses["httpbin.org"]["80"].keys()) == 1 - @mocketize(truesocket_recording_dir=recording_directory) def test_truesendall_with_chunk_recording(self): - url = "http://httpbin.org/range/70000?chunk_size=65536" - - requests.get(url) - resp = requests.get(url) - self.assertEqual(resp.status_code, 200) - - dump_filename = os.path.join( - Mocket.get_truesocket_recording_dir(), Mocket.get_namespace() + ".json" - ) - with io.open(dump_filename) as f: - responses = json.load(f) + with tempfile.TemporaryDirectory() as temp_dir: + with Mocketizer(truesocket_recording_dir=temp_dir): + url = "http://httpbin.org/range/70000?chunk_size=65536" + + requests.get(url) + resp = requests.get(url) + self.assertEqual(resp.status_code, 200) + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + ".json", + ) + with io.open(dump_filename) as f: + responses = json.load(f) - assert len(responses["httpbin.org"]["80"].keys()) == 1 + assert len(responses["httpbin.org"]["80"].keys()) == 1 @mocketize def test_wrongpath_truesendall(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/main/test_http_aiohttp.py new/mocket-3.11.0/tests/main/test_http_aiohttp.py --- old/mocket-3.10.9/tests/main/test_http_aiohttp.py 2022-01-08 17:50:17.000000000 +0100 +++ new/mocket-3.11.0/tests/main/test_http_aiohttp.py 2023-02-19 16:55:48.000000000 +0100 @@ -1,82 +1,79 @@ -import asyncio import json -from unittest import TestCase import aiohttp -import async_timeout +import pytest +from asgiref.sync import async_to_sync from mocket.mocket import Mocket, mocketize from mocket.mockhttp import Entry -from mocket.plugins.httpretty import HTTPretty, httprettified +from mocket.plugins.httpretty import httprettified, httpretty +timeout = aiohttp.ClientTimeout(total=3) -class AioHttpEntryTestCase(TestCase): - @mocketize - def test_http_session(self): - url = "http://httpbin.org/ip" - body = "asd" * 100 - Entry.single_register(Entry.GET, url, body=body, status=404) - Entry.single_register(Entry.POST, url, body=body * 2, status=201) - - async def main(_loop): - async with aiohttp.ClientSession(loop=_loop) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - assert Mocket.last_request().method == "POST" - assert Mocket.last_request().body == body * 6 - - loop = asyncio.get_event_loop() - loop.set_debug(True) - loop.run_until_complete(main(loop)) - self.assertEqual(len(Mocket.request_list()), 2) - - @mocketize - def test_https_session(self): - url = "https://httpbin.org/ip" - body = "asd" * 100 - Entry.single_register(Entry.GET, url, body=body, status=404) - Entry.single_register(Entry.POST, url, body=body * 2, status=201) - - async def main(_loop): - async with aiohttp.ClientSession(loop=_loop) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - - loop = asyncio.get_event_loop() - loop.set_debug(True) - loop.run_until_complete(main(loop)) - self.assertEqual(len(Mocket.request_list()), 2) - - @httprettified - def test_httprettish_session(self): - url = "https://httpbin.org/ip" - HTTPretty.register_uri( - HTTPretty.GET, - url, - body=json.dumps(dict(origin="127.0.0.1")), - ) - - async def main(_loop): - async with aiohttp.ClientSession(loop=_loop) as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 200 - assert await get_response.text() == '{"origin": "127.0.0.1"}' - - loop = asyncio.get_event_loop() - loop.set_debug(True) - loop.run_until_complete(main(loop)) + +@mocketize +def test_http_session(): + url = "http://httpbin.org/ip" + body = "asd" * 100 + Entry.single_register(Entry.GET, url, body=body, status=404) + Entry.single_register(Entry.POST, url, body=body * 2, status=201) + + @async_to_sync + async def perform_aiohttp_transactions(): + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + assert Mocket.last_request().method == "POST" + assert Mocket.last_request().body == body * 6 + + perform_aiohttp_transactions() + assert len(Mocket.request_list()) == 2 + + +@pytest.mark.xfail +@mocketize +def test_https_session(): + url = "https://httpbin.org/ip" + body = "asd" * 100 + Entry.single_register(Entry.GET, url, body=body, status=404) + Entry.single_register(Entry.POST, url, body=body * 2, status=201) + + @async_to_sync + async def perform_aiohttp_transactions(): + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + + perform_aiohttp_transactions() + assert len(Mocket.request_list()) == 2 + + +@pytest.mark.xfail +@httprettified +def test_httprettish_session(): + url = "https://httpbin.org/ip" + httpretty.register_uri( + httpretty.GET, + url, + body=json.dumps(dict(origin="127.0.0.1")), + ) + + @async_to_sync + async def perform_aiohttp_transactions(): + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.get(url) as get_response: + assert get_response.status == 200 + assert await get_response.text() == '{"origin": "127.0.0.1"}' + + perform_aiohttp_transactions() + assert len(httpretty.latest_requests) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/main/test_https.py new/mocket-3.11.0/tests/main/test_https.py --- old/mocket-3.10.9/tests/main/test_https.py 2022-01-08 13:36:13.000000000 +0100 +++ new/mocket-3.11.0/tests/main/test_https.py 2023-02-19 16:55:48.000000000 +0100 @@ -42,22 +42,23 @@ @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') -@mocketize(truesocket_recording_dir=recording_directory) def test_truesendall_with_recording_https(): - url = "https://httpbin.org/ip" + with tempfile.TemporaryDirectory() as temp_dir: + with Mocketizer(truesocket_recording_dir=temp_dir): + url = "https://httpbin.org/ip" + + requests.get(url, headers={"Accept": "application/json"}) + resp = requests.get(url, headers={"Accept": "application/json"}) + assert resp.status_code == 200 + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + ".json", + ) + with io.open(dump_filename) as f: + responses = json.load(f) - requests.get(url, headers={"Accept": "application/json"}) - resp = requests.get(url, headers={"Accept": "application/json"}) - assert resp.status_code == 200 - - dump_filename = os.path.join( - Mocket.get_truesocket_recording_dir(), - Mocket.get_namespace() + ".json", - ) - with io.open(dump_filename) as f: - responses = json.load(f) - - assert len(responses["httpbin.org"]["443"].keys()) == 1 + assert len(responses["httpbin.org"]["443"].keys()) == 1 @pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/main/test_mocket.py new/mocket-3.11.0/tests/main/test_mocket.py --- old/mocket-3.10.9/tests/main/test_mocket.py 2022-04-25 08:49:46.000000000 +0200 +++ new/mocket-3.11.0/tests/main/test_mocket.py 2023-02-19 16:55:48.000000000 +0100 @@ -174,13 +174,13 @@ @pytest.fixture -def fixture(): +def two(): return 2 @mocketize -def test_mocketize_with_fixture(fixture): - assert 2 == fixture +def test_mocketize_with_fixture(two): + assert 2 == two @mocketize diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/main/test_pook.py new/mocket-3.11.0/tests/main/test_pook.py --- old/mocket-3.10.9/tests/main/test_pook.py 2021-03-20 19:51:56.000000000 +0100 +++ new/mocket-3.11.0/tests/main/test_pook.py 2023-02-19 16:55:48.000000000 +0100 @@ -1,30 +1,33 @@ -import pook -import requests +import platform -from mocket.plugins.pook_mock_engine import MocketEngine - -pook.set_mock_engine(MocketEngine) - - -@pook.on -def test_pook_engine(): - - url = "http://twitter.com/api/1/foobar" - status = 404 - response_json = {"error": "foo"} - - mock = pook.get( - url, - headers={"content-type": "application/json"}, - reply=status, - response_json=response_json, - ) - mock.persist() - - requests.get(url) - assert mock.calls == 1 - - resp = requests.get(url) - assert resp.status_code == status - assert resp.json() == response_json - assert mock.calls == 2 +if not platform.python_version().startswith("3.11."): + # it looks like `pook` is not compatible with Python 3.11 + import pook + import requests + + from mocket.plugins.pook_mock_engine import MocketEngine + + pook.set_mock_engine(MocketEngine) + + @pook.on + def test_pook_engine(): + + url = "http://twitter.com/api/1/foobar" + status = 404 + response_json = {"error": "foo"} + + mock = pook.get( + url, + headers={"content-type": "application/json"}, + reply=status, + response_json=response_json, + ) + mock.persist() + + requests.get(url) + assert mock.calls == 1 + + resp = requests.get(url) + assert resp.status_code == status + assert resp.json() == response_json + assert mock.calls == 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/tests37/test_asyncio.py new/mocket-3.11.0/tests/tests37/test_asyncio.py --- old/mocket-3.10.9/tests/tests37/test_asyncio.py 2021-08-31 12:37:51.000000000 +0200 +++ new/mocket-3.11.0/tests/tests37/test_asyncio.py 2023-02-19 16:55:48.000000000 +0100 @@ -2,47 +2,39 @@ import glob import io import json -import shutil import socket import tempfile -from unittest import TestCase -from mocket.mocket import mocketize +from mocket import Mocketizer -class AsyncIoRecordTestCase(TestCase): - temp_dir = tempfile.mkdtemp() +def test_asyncio_record_replay(event_loop): + async def test_asyncio_connection(): + reader, writer = await asyncio.open_connection( + host="google.com", + port=80, + family=socket.AF_INET, + proto=socket.IPPROTO_TCP, + ssl=None, + server_hostname=None, + ) + + buf = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n" + writer.write(buf.encode()) + await writer.drain() + + await reader.readline() + writer.close() + await writer.wait_closed() + + with tempfile.TemporaryDirectory() as temp_dir: + with Mocketizer(truesocket_recording_dir=temp_dir): + event_loop.run_until_complete(test_asyncio_connection()) - @mocketize(truesocket_recording_dir=temp_dir) - def test_asyncio_record_replay(self): - async def test_asyncio_connection(): - reader, writer = await asyncio.open_connection( - host="google.com", - port=80, - family=socket.AF_INET, - proto=socket.IPPROTO_TCP, - ssl=None, - server_hostname=None, - ) - - buf = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n" - writer.write(buf.encode()) - await writer.drain() - - await reader.readline() - writer.close() - await writer.wait_closed() - - loop = asyncio.get_event_loop() - loop.set_debug(True) - loop.run_until_complete(test_asyncio_connection()) - - files = glob.glob(f"{self.temp_dir}/*.json") - self.assertEqual(len(files), 1) + files = glob.glob(f"{temp_dir}/*.json") + assert len(files) == 1 with io.open(files[0]) as f: responses = json.load(f) - self.assertEqual(len(responses["google.com"]["80"].keys()), 1) - - shutil.rmtree(self.temp_dir) + assert len(responses["google.com"]["80"].keys()) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.10.9/tests/tests38/test_http_aiohttp.py new/mocket-3.11.0/tests/tests38/test_http_aiohttp.py --- old/mocket-3.10.9/tests/tests38/test_http_aiohttp.py 2022-01-08 17:50:17.000000000 +0100 +++ new/mocket-3.11.0/tests/tests38/test_http_aiohttp.py 2023-02-19 16:55:48.000000000 +0100 @@ -2,7 +2,8 @@ from unittest import IsolatedAsyncioTestCase import aiohttp -import async_timeout +import httpx +import pytest from mocket.async_mocket import async_mocketize from mocket.mocket import Mocket @@ -11,59 +12,70 @@ class AioHttpEntryTestCase(IsolatedAsyncioTestCase): + timeout = aiohttp.ClientTimeout(total=3) + target_url = "http://httpbin.org/ip" + @async_mocketize async def test_http_session(self): - url = "http://httpbin.org/ip" body = "asd" * 100 - Entry.single_register(Entry.GET, url, body=body, status=404) - Entry.single_register(Entry.POST, url, body=body * 2, status=201) + Entry.single_register(Entry.GET, self.target_url, body=body, status=404) + Entry.single_register(Entry.POST, self.target_url, body=body * 2, status=201) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 - assert Mocket.last_request().method == "POST" - assert Mocket.last_request().body == body * 6 + async with aiohttp.ClientSession(timeout=self.timeout) as session: + async with session.get(self.target_url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(self.target_url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 + assert Mocket.last_request().method == "POST" + assert Mocket.last_request().body == body * 6 self.assertEqual(len(Mocket.request_list()), 2) @async_mocketize async def test_https_session(self): - url = "https://httpbin.org/ip" body = "asd" * 100 - Entry.single_register(Entry.GET, url, body=body, status=404) - Entry.single_register(Entry.POST, url, body=body * 2, status=201) + Entry.single_register(Entry.GET, self.target_url, body=body, status=404) + Entry.single_register(Entry.POST, self.target_url, body=body * 2, status=201) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 404 - assert await get_response.text() == body - - with async_timeout.timeout(3): - async with session.post(url, data=body * 6) as post_response: - assert post_response.status == 201 - assert await post_response.text() == body * 2 + async with aiohttp.ClientSession(timeout=self.timeout) as session: + async with session.get(self.target_url) as get_response: + assert get_response.status == 404 + assert await get_response.text() == body + + async with session.post(self.target_url, data=body * 6) as post_response: + assert post_response.status == 201 + assert await post_response.text() == body * 2 self.assertEqual(len(Mocket.request_list()), 2) + @pytest.mark.xfail @async_httprettified async def test_httprettish_session(self): - url = "https://httpbin.org/ip" HTTPretty.register_uri( HTTPretty.GET, - url, + self.target_url, body=json.dumps(dict(origin="127.0.0.1")), ) - async with aiohttp.ClientSession() as session: - with async_timeout.timeout(3): - async with session.get(url) as get_response: - assert get_response.status == 200 - assert await get_response.text() == '{"origin": "127.0.0.1"}' + async with aiohttp.ClientSession(timeout=self.timeout) as session: + async with session.get(self.target_url) as get_response: + assert get_response.status == 200 + assert await get_response.text() == '{"origin": "127.0.0.1"}' + + @async_httprettified + async def test_httprettish_httpx_session(self): + expected_response = {"origin": "127.0.0.1"} + + HTTPretty.register_uri( + HTTPretty.GET, + self.target_url, + body=json.dumps(expected_response), + ) + + async with httpx.AsyncClient() as client: + response = await client.get(self.target_url) + assert response.status_code == 200 + assert response.json() == expected_response