Hello community, here is the log from the commit of package python-pook for openSUSE:Factory checked in at 2020-03-24 22:36:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pook (Old) and /work/SRC/openSUSE:Factory/.python-pook.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pook" Tue Mar 24 22:36:13 2020 rev:3 rq:787730 version:1.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pook/python-pook.changes 2020-03-18 12:51:39.325184136 +0100 +++ /work/SRC/openSUSE:Factory/.python-pook.new.3160/python-pook.changes 2020-03-24 22:38:17.417262849 +0100 @@ -1,0 +2,7 @@ +Tue Mar 24 09:20:50 UTC 2020 - [email protected] + +- version update to 1.0.0 + * fix(aiohttp): use latest version, allow Python 3.5+ for async http client +- drop python2 support, python-aiohttp required + +------------------------------------------------------------------- Old: ---- pook-0.2.8.tar.gz New: ---- pook-1.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pook.spec ++++++ --- /var/tmp/diff_new_pack.m592Lb/_old 2020-03-24 22:38:18.029263146 +0100 +++ /var/tmp/diff_new_pack.m592Lb/_new 2020-03-24 22:38:18.033263148 +0100 @@ -17,8 +17,10 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} +# requires python-aiohttp +%define skip_python2 1 Name: python-pook -Version: 0.2.8 +Version: 1.0.0 Release: 0 Summary: HTTP traffic mocking and expectations License: MIT @@ -26,8 +28,16 @@ URL: https://github.com/h2non/pook Source: https://files.pythonhosted.org/packages/source/p/pook/pook-%{version}.tar.gz BuildRequires: %{python_module setuptools} +BuildRequires: fdupes BuildRequires: python-rpm-macros +Requires: python-aiohttp +Requires: python-furl >= 0.5.6 +Requires: python-jsonschema >= 2.5.1 +Requires: python-xmltodict >= 0.11.0 +Suggests: python-mock >= 2.0.0 +BuildArch: noarch # SECTION test requirements +BuildRequires: %{python_module aiohttp} BuildRequires: %{python_module furl >= 0.5.6} BuildRequires: %{python_module jsonschema >= 2.5.1} BuildRequires: %{python_module mocket >= 1.6.0} @@ -38,13 +48,6 @@ BuildRequires: %{python_module urllib3 >= 1.19.1} BuildRequires: %{python_module xmltodict >= 0.10.2} # /SECTION -BuildRequires: fdupes -Requires: python-furl >= 0.5.6 -Requires: python-jsonschema >= 2.5.1 -Requires: python-xmltodict >= 0.10.2 -Suggests: python-mock >= 2.0.0 -BuildArch: noarch - %python_subpackages %description ++++++ pook-0.2.8.tar.gz -> pook-1.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/LICENSE new/pook-1.0.0/LICENSE --- old/pook-0.2.8/LICENSE 2019-10-22 21:27:11.000000000 +0200 +++ new/pook-1.0.0/LICENSE 2020-03-19 00:13:25.000000000 +0100 @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2019 Tomás Aparicio +Copyright (c) 2016-2020 Tomás Aparicio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/PKG-INFO new/pook-1.0.0/PKG-INFO --- old/pook-0.2.8/PKG-INFO 2019-10-31 10:56:02.000000000 +0100 +++ new/pook-1.0.0/PKG-INFO 2020-03-19 00:15:30.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pook -Version: 0.2.8 +Version: 1.0.0 Summary: HTTP traffic mocking and expectations made easy Home-page: https://github.com/h2non/pook Author: Tomas Aparicio @@ -509,10 +509,7 @@ Classifier: Development Status :: 5 - Production/Stable Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook/__init__.py new/pook-1.0.0/pook/__init__.py --- old/pook-0.2.8/pook/__init__.py 2019-10-31 10:49:43.000000000 +0100 +++ new/pook-1.0.0/pook/__init__.py 2020-03-19 00:12:59.000000000 +0100 @@ -9,4 +9,4 @@ __license__ = 'MIT' # Current version -__version__ = '0.2.8' +__version__ = '1.0.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook/interceptors/__init__.py new/pook-1.0.0/pook/interceptors/__init__.py --- old/pook-0.2.8/pook/interceptors/__init__.py 2019-10-22 21:14:17.000000000 +0200 +++ new/pook-1.0.0/pook/interceptors/__init__.py 2020-03-19 00:12:59.000000000 +0100 @@ -19,19 +19,19 @@ ] # Import aiohttp in modern Python runtimes -if sys.version_info >= (3, 4, 2): +if sys.version_info >= (3, 5, 0): from .aiohttp import AIOHTTPInterceptor interceptors.append(AIOHTTPInterceptor) -def add(*interceptors): +def add(*custom_interceptors): """ Registers a new HTTP client interceptor. Arguments: - *interceptors (interceptor): interceptor(s) to be added. + *custom_interceptors (interceptor): interceptor(s) to be added. """ - interceptors.append(*interceptors) + interceptors.append(*custom_interceptors) def get(name): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook/interceptors/aiohttp.py new/pook-1.0.0/pook/interceptors/aiohttp.py --- old/pook-0.2.8/pook/interceptors/aiohttp.py 2019-10-22 21:14:17.000000000 +0200 +++ new/pook-1.0.0/pook/interceptors/aiohttp.py 2020-03-19 00:12:59.000000000 +0100 @@ -9,16 +9,20 @@ from unittest import mock if sys.version_info < (3,): # Python 2 - from urlparse import urlunparse + from urlparse import urlunparse, urlencode from httplib import responses as http_reasons else: # Python 3 - from urllib.parse import urlunparse + from urllib.parse import urlunparse, urlencode from http.client import responses as http_reasons -if sys.version_info >= (3, 4, 2): # Python 3.4.2+ +if sys.version_info >= (3, 5, 0): # Python 3.5+ import asyncio + from aiohttp.helpers import TimerNoop + from aiohttp.streams import EmptyStreamReader else: asyncio = None + TimerNoop = None + EmptyStreamReader = None # Try to load yarl URL parser package used by aiohttp try: @@ -35,13 +39,33 @@ RESPONSE_PATH = 'aiohttp.client_reqrep' +class SimpleContent(EmptyStreamReader): + def __init__(self, content, *args, **kwargs): + super().__init__(*args, **kwargs) + self.content = content + + @asyncio.coroutine + def read(self, n=-1): + return self.content + + def HTTPResponse(*args, **kw): # Dynamically load package module = __import__(RESPONSE_PATH, fromlist=(RESPONSE_CLASS,)) ClientResponse = getattr(module, RESPONSE_CLASS) # Return response instance - return ClientResponse(*args, **kw) + return ClientResponse( + *args, + request_info=mock.Mock(), + writer=mock.Mock(), + continue100=None, + timer=TimerNoop(), + traces=[], + loop=mock.Mock(), + session=mock.Mock(), + **kw + ) class AIOHTTPInterceptor(BaseInterceptor): @@ -64,7 +88,12 @@ req.extra = kw # Compose URL - req.url = str(url) + if not kw.get('params'): + req.url = str(url) + else: + req.url = str(url) + '?' + urlencode( + [(x, y) for x, y in kw['params'].items()] + ) # Match the request against the registered mocks in pook mock = self.engine.match(req) @@ -98,16 +127,19 @@ _res._should_close = False # Add response headers - _res.raw_headers = tuple(headers) - _res.headers = multidict.CIMultiDictProxy( + _res._raw_headers = tuple(headers) + _res._headers = multidict.CIMultiDictProxy( multidict.CIMultiDict(headers) ) - # Define `_content` attribute with an empty string to - # force do not read from stream (which won't exists) - _res._content = '' if res._body: - _res._content = res._body.encode('utf-8', errors='replace') + _res.content = SimpleContent( + res._body.encode('utf-8', errors='replace'), + ) + else: + # Define `_content` attribute with an empty string to + # force do not read from stream (which won't exists) + _res.content = EmptyStreamReader() # Return response based on mock definition return _res diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook/interceptors/urllib3.py new/pook-1.0.0/pook/interceptors/urllib3.py --- old/pook-0.2.8/pook/interceptors/urllib3.py 2019-10-22 21:14:17.000000000 +0200 +++ new/pook-1.0.0/pook/interceptors/urllib3.py 2020-03-19 00:12:59.000000000 +0100 @@ -11,9 +11,15 @@ from unittest import mock if sys.version_info < (3,): # Python 2 - from httplib import responses as http_reasons + from httplib import ( + responses as http_reasons, + HTTPResponse as ClientHTTPResponse, + ) else: # Python 3 - from http.client import responses as http_reasons + from http.client import ( + responses as http_reasons, + HTTPResponse as ClientHTTPResponse, + ) PATCHES = ( 'requests.packages.urllib3.connectionpool.HTTPConnectionPool.urlopen', @@ -48,6 +54,17 @@ return io.BytesIO(string) +def is_chunked_response(headers): + tencoding = dict(headers).get("Transfer-Encoding", "").lower() + return "chunked" in tencoding.split(",") + + +class MockSock(object): + @classmethod + def makefile(cls, *args, **kwargs): + return + + class FakeHeaders(list): def get_all(self, key, default=None): key = key.lower() @@ -56,11 +73,53 @@ class FakeResponse(object): - def __init__(self, headers): + def __init__(self, method, headers): + self._method = method # name expected by urllib3 self.msg = FakeHeaders(headers) + self.closed = False + + def close(self): + self.closed = True def isclosed(self): - return False + return self.closed + + +class FakeChunkedResponseBody(object): + def __init__(self, chunks): + # append a terminating chunk + chunks.append(b'') + + self.position = 0 + self.stream = b''.join([self._encode(c) for c in chunks]) + self.closed = False + + def _encode(self, chunk): + length = '%X\r\n' % len(chunk) + return length.encode() + chunk + b'\r\n' + + def read_chunk(self, amt=-1, whole=False): + if whole or amt == -1: + end_idx = self.stream.index(b'\r\n', self.position) + 2 + else: + end_idx = self.position + amt + + chunk = self.stream[self.position:end_idx] + self.position = end_idx + + return chunk + + def readline(self): + return self.read_chunk(whole=True) + + def read(self, amt=-1): + return self.read_chunk(amt) + + def flush(self): + pass + + def close(self): + self.closed = True class Urllib3Interceptor(BaseInterceptor): @@ -96,23 +155,34 @@ if not mock: return urlopen(pool, method, url, body=body, headers=headers, **kw) - # Shortcut to mock response + # Shortcut to mock response and response body res = mock._response + body = res._body # Aggregate headers as list of tuples for interface compatibility headers = [] for key in res._headers: headers.append((key, res._headers[key])) + if is_chunked_response(headers): + body_chunks = body if isinstance(body, list) else [body] + body_chunks = [chunk.encode() for chunk in body_chunks] + + body = ClientHTTPResponse(MockSock) + body.fp = FakeChunkedResponseBody(body_chunks) + else: + # Assume that the body is a bytes-like object + body = body_io(body) + # Return mocked HTTP response return HTTPResponse( path, - body=body_io(res._body), + body=body, status=res._status, headers=headers, preload_content=False, reason=http_reasons.get(res._status), - original_response=FakeResponse(headers), + original_response=FakeResponse(method, headers), ) def _patch(self, path): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook/response.py new/pook-1.0.0/pook/response.py --- old/pook-0.2.8/pook/response.py 2019-10-22 21:14:17.000000000 +0200 +++ new/pook-1.0.0/pook/response.py 2020-03-19 00:12:59.000000000 +0100 @@ -145,12 +145,13 @@ self._headers['Content-Type'] = TYPES.get(name, name) @fluent - def body(self, body): + def body(self, body, chunked=False): """ Defines response body data. Arguments: - body (str|bytes): response body to use. + body (str|bytes|list): response body to use. + chunked (bool): return a chunked response. Returns: self: ``pook.Response`` current instance. @@ -160,6 +161,9 @@ self._body = body + if chunked: + self.header('Transfer-Encoding', 'chunked') + @fluent def json(self, data): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook.egg-info/PKG-INFO new/pook-1.0.0/pook.egg-info/PKG-INFO --- old/pook-0.2.8/pook.egg-info/PKG-INFO 2019-10-31 10:56:02.000000000 +0100 +++ new/pook-1.0.0/pook.egg-info/PKG-INFO 2020-03-19 00:15:29.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pook -Version: 0.2.8 +Version: 1.0.0 Summary: HTTP traffic mocking and expectations made easy Home-page: https://github.com/h2non/pook Author: Tomas Aparicio @@ -509,10 +509,7 @@ Classifier: Development Status :: 5 - Production/Stable Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/pook.egg-info/SOURCES.txt new/pook-1.0.0/pook.egg-info/SOURCES.txt --- old/pook-0.2.8/pook.egg-info/SOURCES.txt 2019-10-31 10:56:02.000000000 +0100 +++ new/pook-1.0.0/pook.egg-info/SOURCES.txt 2020-03-19 00:15:29.000000000 +0100 @@ -63,6 +63,8 @@ tests/unit/mock_test.py tests/unit/regex_test.py tests/unit/interceptors/__init__.py +tests/unit/interceptors/module_test.py +tests/unit/interceptors/urllib3_test.py tests/unit/matchers/__init__.py tests/unit/matchers/base_test.py tests/unit/matchers/body_test.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/requirements-dev.txt new/pook-1.0.0/requirements-dev.txt --- old/pook-0.2.8/requirements-dev.txt 2019-10-22 21:14:17.000000000 +0200 +++ new/pook-1.0.0/requirements-dev.txt 2020-03-19 00:12:59.000000000 +0100 @@ -10,5 +10,5 @@ requests>=2.20.0 urllib3>=1.24.2 bumpversion~=0.5.3 -aiohttp~=1.1.5 ; python_version >= '3.4.2' +aiohttp~=3.6.2 ; python_version >= '3.5.0' mocket~=1.6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/setup.py new/pook-1.0.0/setup.py --- old/pook-0.2.8/setup.py 2019-10-31 10:49:34.000000000 +0100 +++ new/pook-1.0.0/setup.py 2020-03-19 00:13:14.000000000 +0100 @@ -5,7 +5,7 @@ ==== Versatile HTTP traffic mocking and expectations made easy in Python. -:copyright: (c) 2016-2019 Tomas Aparicio +:copyright: (c) 2016-2020 Tomas Aparicio :license: MIT """ @@ -91,15 +91,12 @@ 'Development Status :: 5 - Production/Stable', 'Natural Language :: English', 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', - 'Topic :: Software Development', + 'Topic :: Software Development', 'Topic :: Software Development :: Libraries :: Python Modules', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/tests/unit/interceptors/module_test.py new/pook-1.0.0/tests/unit/interceptors/module_test.py --- old/pook-0.2.8/tests/unit/interceptors/module_test.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pook-1.0.0/tests/unit/interceptors/module_test.py 2020-03-19 00:12:59.000000000 +0100 @@ -0,0 +1,11 @@ +from pook import interceptors + + +class CustomInterceptor(interceptors.BaseInterceptor): + pass + + +def test_add_custom_interceptor(): + interceptors.add(CustomInterceptor) + + assert CustomInterceptor in interceptors.interceptors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pook-0.2.8/tests/unit/interceptors/urllib3_test.py new/pook-1.0.0/tests/unit/interceptors/urllib3_test.py --- old/pook-0.2.8/tests/unit/interceptors/urllib3_test.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pook-1.0.0/tests/unit/interceptors/urllib3_test.py 2020-03-19 00:12:59.000000000 +0100 @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import urllib3 +import pook + + [email protected] +def assert_chunked_response(input_data, expected): + (pook.get('httpbin.org/foo') + .reply(204) + .body(input_data, chunked=True)) + + http = urllib3.PoolManager() + r = http.request('GET', 'httpbin.org/foo') + + assert r.status == 204 + + # py2 returns decoded chunks, while py3 does not + chunks = list(r.read_chunked()) + chunks = [c.decode() if isinstance(c, bytes) else c for c in chunks] + assert chunks == expected + + +def test_chunked_response_list(): + assert_chunked_response(['a', 'b', 'c'], ['a', 'b', 'c']) + + +def test_chunked_response_str(): + assert_chunked_response('text', ['text']) + + +def test_chunked_response_byte(): + assert_chunked_response(b'byteman', ['byteman']) + + +def test_chunked_response_empty(): + assert_chunked_response('', []) + + +def test_chunked_response_contains_newline(): + assert_chunked_response('newline\r\n', ['newline\r\n'])
