Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pytest-httpbin for openSUSE:Factory checked in at 2023-11-08 22:17:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest-httpbin (Old) and /work/SRC/openSUSE:Factory/.python-pytest-httpbin.new.17445 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-httpbin" Wed Nov 8 22:17:12 2023 rev:12 rq:1124086 version:2.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest-httpbin/python-pytest-httpbin.changes 2023-04-25 16:53:36.482268682 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytest-httpbin.new.17445/python-pytest-httpbin.changes 2023-11-08 22:17:29.574655215 +0100 @@ -1,0 +2,12 @@ +Tue Nov 7 19:42:56 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 2.0.0: + * This is a major release since it drops comparability with + some older versions of python. + * Drop support for Python 2.6, 2.7, 3.4, 3.5 and 3.6 (#68) + * Add support for Python 3.7, 3.8, 3.9 and 3.10 (#68) + * Avoid deprecation warnings and resource warnings (#71) + * Add support for Python 3.11 and 3.12, drop dependency on six +- drop python-pytest-httpbin-no-six.patch (upstream) + +------------------------------------------------------------------- Old: ---- pytest-httpbin-1.0.2.tar.gz python-pytest-httpbin-no-six.patch New: ---- pytest-httpbin-2.0.0.tar.gz BETA DEBUG BEGIN: Old: * Add support for Python 3.11 and 3.12, drop dependency on six - drop python-pytest-httpbin-no-six.patch (upstream) BETA DEBUG END: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest-httpbin.spec ++++++ --- /var/tmp/diff_new_pack.kvLXwi/_old 2023-11-08 22:17:30.186677699 +0100 +++ /var/tmp/diff_new_pack.kvLXwi/_new 2023-11-08 22:17:30.190677846 +0100 @@ -16,10 +16,9 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} %{?sle15_python_module_pythons} Name: python-pytest-httpbin -Version: 1.0.2 +Version: 2.0.0 Release: 0 Summary: Web service for testing HTTP libraries License: MIT @@ -27,8 +26,6 @@ URL: https://github.com/kevin1024/pytest-httpbin Source: https://files.pythonhosted.org/packages/source/p/pytest-httpbin/pytest-httpbin-%{version}.tar.gz Source99: pytest-httpbin-rpmlintrc -# https://github.com/kevin1024/pytest-httpbin/issues/75 -Patch0: python-pytest-httpbin-no-six.patch BuildRequires: %{python_module httpbin} BuildRequires: %{python_module pytest} BuildRequires: %{python_module requests} @@ -50,8 +47,7 @@ fixture. %prep -%setup -q -n pytest-httpbin-%{version} -%patch0 -p1 +%autosetup -p1 -n pytest-httpbin-%{version} %build %python_build ++++++ pytest-httpbin-1.0.2.tar.gz -> pytest-httpbin-2.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/PKG-INFO new/pytest-httpbin-2.0.0/PKG-INFO --- old/pytest-httpbin-1.0.2/PKG-INFO 2022-02-25 11:31:20.833808000 +0100 +++ new/pytest-httpbin-2.0.0/PKG-INFO 2023-05-08 22:01:54.592055600 +0200 @@ -1,25 +1,25 @@ Metadata-Version: 2.1 Name: pytest-httpbin -Version: 1.0.2 +Version: 2.0.0 Summary: Easily test your HTTP library against a local copy of httpbin Home-page: https://github.com/kevin1024/pytest-httpbin Author: Kevin McCarthy Author-email: m...@kevinmccarthy.org License: MIT Keywords: pytest-httpbin testing pytest httpbin -Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Libraries Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.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 +Requires-Python: >=3.7 Description-Content-Type: text/x-rst Provides-Extra: test @@ -53,5 +53,3 @@ Check out `the full documentation`_ on the github page. .. _the full documentation: https://github.com/kevin1024/pytest-httpbin - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/README.md new/pytest-httpbin-2.0.0/README.md --- old/pytest-httpbin-1.0.2/README.md 2022-02-25 11:29:58.000000000 +0100 +++ new/pytest-httpbin-2.0.0/README.md 2023-05-08 22:01:08.000000000 +0200 @@ -2,9 +2,16 @@ [](https://github.com/kevin1024/pytest-httpbin/actions/workflows/main.yaml) -[httpbin](https://httpbin.org/) is an amazing web service for testing HTTP libraries. It has several great endpoints that can test pretty much everything you need in a HTTP library. The only problem is: maybe you don't want to wait for your tests to travel across the Internet and back to make assertions against a remote web service (speed), and maybe you want to work offline (convenience). - -Enter **pytest-httpbin**. Pytest-httpbin creates a [pytest fixture](https://pytest.org/latest/fixture.html) that is dependency-injected into your tests. It automatically starts up a HTTP server in a separate thread running httpbin and provides your test with the URL in the fixture. Check out this example: +[httpbin](https://httpbin.org/) is an amazing web service for testing HTTP libraries. It +has several great endpoints that can test pretty much everything you need in a HTTP +library. The only problem is: maybe you don't want to wait for your tests to travel +across the Internet and back to make assertions against a remote web service (speed), +and maybe you want to work offline (convenience). + +Enter **pytest-httpbin**. Pytest-httpbin creates a +[pytest fixture](https://pytest.org/latest/fixture.html) that is dependency-injected +into your tests. It automatically starts up a HTTP server in a separate thread running +httpbin and provides your test with the URL in the fixture. Check out this example: ```python def test_that_my_library_works_kinda_ok(httpbin): @@ -22,7 +29,6 @@  - # HTTPS support pytest-httpbin also supports HTTPS: @@ -32,9 +38,15 @@ assert requests.get(httpbin_secure.url + '/get/').status_code == 200 ``` -It's actually starting 2 web servers in separate threads in the background: one HTTP and one HTTPS. The servers are started on a random port (see below for fixed port support), on the loopback interface on your machine. Pytest-httpbin includes a self-signed certificate. If your library verifies certificates against a CA (and it should), you'll have to add the CA from pytest-httpbin. The path to the pytest-httpbin CA bundle can by found like this `python -m pytest_httpbin.certs`. +It's actually starting 2 web servers in separate threads in the background: one HTTP and +one HTTPS. The servers are started on a random port (see below for fixed port support), +on the loopback interface on your machine. Pytest-httpbin includes a self-signed +certificate. If your library verifies certificates against a CA (and it should), you'll +have to add the CA from pytest-httpbin. The path to the pytest-httpbin CA bundle can by +found like this `python -m pytest_httpbin.certs`. -For example in requests, you can set the `REQUESTS_CA_BUNDLE` python path. You can run your tests like this: +For example in requests, you can set the `REQUESTS_CA_BUNDLE` python path. You can run +your tests like this: ```bash REQUESTS_CA_BUNDLE=`python -m pytest_httpbin.certs` py.test tests/ @@ -44,31 +56,39 @@ The injected object has the following attributes: - * url - * port - * host +- url +- port +- host and the following methods: - * join(string): Returns the results of calling `urlparse.urljoin` with the url from the injected server automatically applied as the first argument. You supply the second argument +- join(string): Returns the results of calling `urlparse.urljoin` with the url from the + injected server automatically applied as the first argument. You supply the second + argument -Also, I defined `__add__` on the object to append to `httpbin.url`. This means you can do stuff like `httpbin + '/get'` instead of `httpbin.url + '/get'`. +Also, I defined `__add__` on the object to append to `httpbin.url`. This means you can +do stuff like `httpbin + '/get'` instead of `httpbin.url + '/get'`. ## Testing both HTTP and HTTPS endpoints with one test -If you ever find yourself needing to test both the http and https version of and endpoint, you can use the `httpbin_both` funcarg like this: - +If you ever find yourself needing to test both the http and https version of and +endpoint, you can use the `httpbin_both` funcarg like this: ```python def test_that_my_library_works_kinda_ok(httpbin_both): assert requests.get(httpbin_both.url + '/get/').status_code == 200 ``` -Through the magic of pytest parametrization, this function will actually execute twice: once with an http url and once with an https url. +Through the magic of pytest parametrization, this function will actually execute twice: +once with an http url and once with an https url. ## Using pytest-httpbin with unittest-style test cases -I have provided 2 additional fixtures to make testing with class-based tests easier. I have also provided a couple decorators that provide some syntactic sugar around the pytest method of adding the fixtures to class-based tests. Just add the `use_class_based_httpbin` and/or `use_class_based_httpbin_secure` class decorators to your class, and then you can access httpbin using self.httpbin and self.httpbin_secure. +I have provided 2 additional fixtures to make testing with class-based tests easier. I +have also provided a couple decorators that provide some syntactic sugar around the +pytest method of adding the fixtures to class-based tests. Just add the +`use_class_based_httpbin` and/or `use_class_based_httpbin_secure` class decorators to +your class, and then you can access httpbin using self.httpbin and self.httpbin_secure. ```python import pytest_httpbin @@ -85,7 +105,10 @@ ## Running the server on fixed port -Sometimes a randomized port can be a problem. Worry not, you can fix the port number to a desired value with the `HTTPBIN_HTTP_PORT` and `HTTPBIN_HTTPS_PORT` environment variables. If those are defined during pytest plugins are loaded, `httbin` and `httpbin_secure` fixtures will run on given ports. You can run your tests like this: +Sometimes a randomized port can be a problem. Worry not, you can fix the port number to +a desired value with the `HTTPBIN_HTTP_PORT` and `HTTPBIN_HTTPS_PORT` environment +variables. If those are defined during pytest plugins are loaded, `httbin` and +`httpbin_secure` fixtures will run on given ports. You can run your tests like this: ```bash HTTPBIN_HTTP_PORT=8080 HTTPBIN_HTTPS_PORT=8443 py.test tests/ @@ -96,23 +119,29 @@ [](https://pypi.org/project/pytest-httpbin/) [](https://pypi.org/project/pytest-httpbin/) -To install from [PyPI](https://pypi.org/project/pytest-httpbin/), all you need to do is this: +To install from [PyPI](https://pypi.org/project/pytest-httpbin/), all you need to do is +this: ```bash pip install pytest-httpbin ``` -and your tests executed by pytest all will have access to the `httpbin` and `httpbin_secure` funcargs. Cool right? +and your tests executed by pytest all will have access to the `httpbin` and +`httpbin_secure` funcargs. Cool right? ## Support and dependencies -pytest-httpbin supports Python 2.6, 2.7, 3.4-3.6, and pypy. It will automatically install httpbin and flask when you install it from PyPI. +pytest-httpbin supports Python 2.6, 2.7, 3.4-3.6, and pypy. It will automatically +install httpbin and flask when you install it from PyPI. -[httpbin](https://github.com/postmanlabs/httpbin) itself does not support python 2.6 as of version 0.6.0, when the Flask-common dependency was added. If you need python 2.6 support pin the httpbin version to 0.5.0 +[httpbin](https://github.com/postmanlabs/httpbin) itself does not support python 2.6 as +of version 0.6.0, when the Flask-common dependency was added. If you need python 2.6 +support pin the httpbin version to 0.5.0 ## Running the pytest-httpbin test suite -If you want to run pytest-httpbin's test suite, you'll need to install requests and pytest, and then use the ./runtests.sh script. +If you want to run pytest-httpbin's test suite, you'll need to install requests and +pytest, and then use the ./runtests.sh script. ```bash pip install pytest @@ -127,60 +156,66 @@ ``` ## Changelog - -* 1.0.2 - * Switch from travis to github actions - * This will be the last release to support Python 2.6, 2.7 or 3.6 -* 1.0.1 - * httpbin_secure: fix redirect Location to have "https://" scheme (#62) - thanks @immerrr - * Include regression tests in pypi tarball (#56) - thanks @kmosiejczuk -* 1.0.0 - * Update included self-signed cert to include IP address in SAN (See #52). Full version bump because this could be a breaking change for those depending on the certificate missing the IP address in the SAN (as it seems the requests test suite does) - * Only use @pytest.fixture decorator once (thanks @hroncok) - * Fix a few README typos (thanks @hemberger) -* 0.3.0 - * Allow to run httpbin on fixed port using environment variables (thanks @hroncok) - * Allow server to be thread.join()ed (thanks @graingert) - * Add support for Python 3.6 (thanks @graingert) -* 0.2.3: - * Another attempt to fix #32 (Rare bug, only happens on Travis) -* 0.2.2: - * Fix bug with python3 -* 0.2.1: - * Attempt to fix strange, impossible-to-reproduce bug with broken SSL certs - that only happens on Travis (#32) [Bad release, breaks py3] -* 0.2.0: - * Remove threaded HTTP server. I built it for Requests, but they deleted - their threaded test since it didn't really work very well. The threaded - server seems to cause some strange problems with HTTP chunking, so I'll - just remove it since nobody is using it (I hope) -* 0.1.1: - * Fix weird hang with SSL on pypy (again) -* 0.1.0: - * Update server to use multithreaded werkzeug server -* 0.0.7: - * Update the certificates (they expired) -* 0.0.6: - * Fix an issue where pypy was hanging when a request was made with an invalid +- 2.0.0 + - Drop support for Python 2.6, 2.7, 3.4, 3.5 and 3.6 (#68) + - Add support for Python 3.7, 3.8, 3.9 and 3.10 (#68) + - Avoid deprecation warnings and resource warnings (#71) + - Add support for Python 3.11 and 3.12, drop dependency on six (#76) +- 1.0.2 + - Switch from travis to github actions + - This will be the last release to support Python 2.6, 2.7 or 3.6 +- 1.0.1 + - httpbin_secure: fix redirect Location to have "https://" scheme (#62) - thanks + @immerrr + - Include regression tests in pypi tarball (#56) - thanks @kmosiejczuk +- 1.0.0 + - Update included self-signed cert to include IP address in SAN (See #52). Full + version bump because this could be a breaking change for those depending on the + certificate missing the IP address in the SAN (as it seems the requests test suite + does) + - Only use @pytest.fixture decorator once (thanks @hroncok) + - Fix a few README typos (thanks @hemberger) +- 0.3.0 + - Allow to run httpbin on fixed port using environment variables (thanks @hroncok) + - Allow server to be thread.join()ed (thanks @graingert) + - Add support for Python 3.6 (thanks @graingert) +- 0.2.3: + - Another attempt to fix #32 (Rare bug, only happens on Travis) +- 0.2.2: + - Fix bug with python3 +- 0.2.1: + - Attempt to fix strange, impossible-to-reproduce bug with broken SSL certs that only + happens on Travis (#32) [Bad release, breaks py3] +- 0.2.0: + - Remove threaded HTTP server. I built it for Requests, but they deleted their + threaded test since it didn't really work very well. The threaded server seems to + cause some strange problems with HTTP chunking, so I'll just remove it since nobody + is using it (I hope) +- 0.1.1: + - Fix weird hang with SSL on pypy (again) +- 0.1.0: + - Update server to use multithreaded werkzeug server +- 0.0.7: + - Update the certificates (they expired) +- 0.0.6: + - Fix an issue where pypy was hanging when a request was made with an invalid certificate -* 0.0.5: - * Fix broken version parsing in 0.0.4 -* 0.0.4: - * **Bad release: Broken version parsing** - * Fix `BadStatusLine` error that occurs when sending multiple requests - in a single session (PR #16). Thanks @msabramo! - * Fix #9 ("Can't be installed at the same time than pytest?") (PR - #14). Thanks @msabramo! - * Add `httpbin_ca_bundle` pytest fixture. With this fixture there is - no need to specify the bundle on every request, as it will - automatically set `REQUESTS_CA_BUNDLE` if using - [requests](https://docs.python-requests.org/). And you don't have to - care about where it is located (PR #8). Thanks @t-8ch! -* 0.0.3: Add a couple test fixtures to make testing old class-based test suites - easier -* 0.0.2: Fixed a couple bugs with the wsgiref server to bring behavior in line - with httpbin.org, thanks @jakubroztocil for the bug reports -* 0.0.1: Initial release +- 0.0.5: + - Fix broken version parsing in 0.0.4 +- 0.0.4: + - **Bad release: Broken version parsing** + - Fix `BadStatusLine` error that occurs when sending multiple requests in a single + session (PR #16). Thanks @msabramo! + - Fix #9 ("Can't be installed at the same time than pytest?") (PR #14). Thanks + @msabramo! + - Add `httpbin_ca_bundle` pytest fixture. With this fixture there is no need to + specify the bundle on every request, as it will automatically set + `REQUESTS_CA_BUNDLE` if using [requests](https://docs.python-requests.org/). And you + don't have to care about where it is located (PR #8). Thanks @t-8ch! +- 0.0.3: Add a couple test fixtures to make testing old class-based test suites easier +- 0.0.2: Fixed a couple bugs with the wsgiref server to bring behavior in line with + httpbin.org, thanks @jakubroztocil for the bug reports +- 0.0.1: Initial release ## License @@ -188,20 +223,19 @@ Copyright (c) 2014-2019 Kevin McCarthy -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin/__init__.py new/pytest-httpbin-2.0.0/pytest_httpbin/__init__.py --- old/pytest-httpbin-1.0.2/pytest_httpbin/__init__.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin/__init__.py 2023-05-08 22:01:08.000000000 +0200 @@ -2,12 +2,11 @@ import pytest - here = os.path.dirname(__file__) version_file = os.path.join(here, "version.py") with open(version_file) as f: - code = compile(f.read(), version_file, 'exec') + code = compile(f.read(), version_file, "exec") exec(code) use_class_based_httpbin = pytest.mark.usefixtures("class_based_httpbin") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin/certs.py new/pytest-httpbin-2.0.0/pytest_httpbin/certs.py --- old/pytest-httpbin-1.0.2/pytest_httpbin/certs.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin/certs.py 2023-05-08 22:01:08.000000000 +0200 @@ -15,7 +15,8 @@ def where(): """Return the preferred certificate bundle.""" # vendored bundle inside Requests - return os.path.join(os.path.dirname(__file__), 'certs', 'cacert.pem') + return os.path.join(os.path.dirname(__file__), "certs", "cacert.pem") -if __name__ == '__main__': + +if __name__ == "__main__": print(where()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin/plugin.py new/pytest-httpbin-2.0.0/pytest_httpbin/plugin.py --- old/pytest-httpbin-1.0.2/pytest_httpbin/plugin.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin/plugin.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,41 +1,39 @@ -from __future__ import absolute_import import pytest from httpbin import app as httpbin_app -from . import serve, certs -@pytest.fixture(scope='session') +from . import certs, serve + + +@pytest.fixture(scope="session") def httpbin(request): - server = serve.Server(application=httpbin_app) - server.start() - request.addfinalizer(server.stop) - return server + with serve.Server(application=httpbin_app) as server: + yield server -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def httpbin_secure(request): - server = serve.SecureServer(application=httpbin_app) - server.start() - request.addfinalizer(server.stop) - return server + with serve.SecureServer(application=httpbin_app) as server: + yield server -@pytest.fixture(scope='session', params=['http', 'https']) +@pytest.fixture(scope="session", params=["http", "https"]) def httpbin_both(request, httpbin, httpbin_secure): - if request.param == 'http': + if request.param == "http": return httpbin - elif request.param == 'https': + elif request.param == "https": return httpbin_secure -@pytest.fixture(scope='class') +@pytest.fixture(scope="class") def class_based_httpbin(request, httpbin): request.cls.httpbin = httpbin -@pytest.fixture(scope='class') + +@pytest.fixture(scope="class") def class_based_httpbin_secure(request, httpbin_secure): request.cls.httpbin_secure = httpbin_secure -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def httpbin_ca_bundle(monkeypatch): - monkeypatch.setenv('REQUESTS_CA_BUNDLE', certs.where()) + monkeypatch.setenv("REQUESTS_CA_BUNDLE", certs.where()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin/serve.py new/pytest-httpbin-2.0.0/pytest_httpbin/serve.py --- old/pytest-httpbin-1.0.2/pytest_httpbin/serve.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin/serve.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,34 +1,31 @@ import os -import threading import ssl -from wsgiref.simple_server import WSGIServer, make_server, WSGIRequestHandler +import threading +from urllib.parse import urljoin from wsgiref.handlers import SimpleHandler -from six.moves.urllib.parse import urljoin +from wsgiref.simple_server import WSGIRequestHandler, WSGIServer, make_server - -CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs') +CERT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "certs") class ServerHandler(SimpleHandler): - - server_software = 'Pytest-HTTPBIN/0.1.0' - http_version = '1.1' + server_software = "Pytest-HTTPBIN/0.1.0" + http_version = "1.1" def cleanup_headers(self): SimpleHandler.cleanup_headers(self) - self.headers['Connection'] = 'Close' + self.headers["Connection"] = "Close" def close(self): try: self.request_handler.log_request( - self.status.split(' ', 1)[0], self.bytes_sent + self.status.split(" ", 1)[0], self.bytes_sent ) finally: SimpleHandler.close(self) class Handler(WSGIRequestHandler): - def handle(self): """Handle a single HTTP request""" @@ -39,7 +36,7 @@ handler = ServerHandler( self.rfile, self.wfile, self.get_stderr(), self.get_environ() ) - handler.request_handler = self # backpointer for logging + handler.request_handler = self # backpointer for logging handler.run(self.server.get_app()) def get_environ(self): @@ -49,28 +46,28 @@ """ # Note: Can't use super since this is an oldstyle class in python 2.x environ = WSGIRequestHandler.get_environ(self).copy() - if self.headers.get('content-type') is None: - del environ['CONTENT_TYPE'] + if self.headers.get("content-type") is None: + del environ["CONTENT_TYPE"] return environ class SecureWSGIServer(WSGIServer): - def finish_request(self, request, client_address): """ Negotiates SSL and then mimics BaseServer behavior. """ request.settimeout(1.0) try: - ssock = ssl.wrap_socket( - request, - keyfile=os.path.join(CERT_DIR, 'key.pem'), - certfile=os.path.join(CERT_DIR, 'cert.pem'), - server_side=True, - suppress_ragged_eofs=False, + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain( + os.path.join(CERT_DIR, "cert.pem"), + os.path.join(CERT_DIR, "key.pem"), ) - self.base_environ['HTTPS'] = 'yes' - self.RequestHandlerClass(ssock, client_address, self) + with context.wrap_socket( + request, server_side=True, suppress_ragged_eofs=False + ) as ssock: + self.base_environ["HTTPS"] = "yes" + self.RequestHandlerClass(ssock, client_address, self) except Exception as e: print("pytest-httpbin server hit an exception serving request: %s" % e) print("attempting to ignore so the rest of the tests can run") @@ -78,27 +75,23 @@ # Thanks, WSGIRequestHandler!! -class Server(object): +class Server: """ HTTP server running a WSGI application in its own thread. """ - port_envvar = 'HTTPBIN_HTTP_PORT' + port_envvar = "HTTPBIN_HTTP_PORT" - def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs): + def __init__(self, host="127.0.0.1", port=0, application=None, **kwargs): self.app = application if self.port_envvar in os.environ: port = int(os.environ[self.port_envvar]) self._server = make_server( - host, - port, - self.app, - handler_class=Handler, - **kwargs + host, port, self.app, handler_class=Handler, **kwargs ) self.host = self._server.server_address[0] self.port = self._server.server_address[1] - self.protocol = 'http' + self.protocol = "http" self._thread = threading.Thread( name=self.__class__, @@ -106,12 +99,22 @@ ) def __del__(self): - if hasattr(self, '_server'): + if hasattr(self, "_server"): self.stop() def start(self): self._thread.start() + def __enter__(self): + self.start() + return self + + def __exit__(self, *args, **kwargs): + self.stop() + suppress_exc = self._server.__exit__(*args, **kwargs) + self._thread.join() + return suppress_exc + def __add__(self, other): return self.url + other @@ -120,16 +123,16 @@ @property def url(self): - return '{0}://{1}:{2}'.format(self.protocol, self.host, self.port) + return f"{self.protocol}://{self.host}:{self.port}" def join(self, url, allow_fragments=True): return urljoin(self.url, url, allow_fragments=allow_fragments) class SecureServer(Server): - port_envvar = 'HTTPBIN_HTTPS_PORT' + port_envvar = "HTTPBIN_HTTPS_PORT" - def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs): - kwargs['server_class'] = SecureWSGIServer - super(SecureServer, self).__init__(host, port, application, **kwargs) - self.protocol = 'https' + def __init__(self, host="127.0.0.1", port=0, application=None, **kwargs): + kwargs["server_class"] = SecureWSGIServer + super().__init__(host, port, application, **kwargs) + self.protocol = "https" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin/version.py new/pytest-httpbin-2.0.0/pytest_httpbin/version.py --- old/pytest-httpbin-1.0.2/pytest_httpbin/version.py 2022-02-25 11:28:55.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin/version.py 2023-05-08 22:01:08.000000000 +0200 @@ -1 +1 @@ -__version__ = '1.0.2' +__version__ = "2.0.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/PKG-INFO new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/PKG-INFO --- old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/PKG-INFO 2022-02-25 11:31:20.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/PKG-INFO 2023-05-08 22:01:54.000000000 +0200 @@ -1,25 +1,25 @@ Metadata-Version: 2.1 Name: pytest-httpbin -Version: 1.0.2 +Version: 2.0.0 Summary: Easily test your HTTP library against a local copy of httpbin Home-page: https://github.com/kevin1024/pytest-httpbin Author: Kevin McCarthy Author-email: m...@kevinmccarthy.org License: MIT Keywords: pytest-httpbin testing pytest httpbin -Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Topic :: Software Development :: Testing Classifier: Topic :: Software Development :: Libraries Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.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 +Requires-Python: >=3.7 Description-Content-Type: text/x-rst Provides-Extra: test @@ -53,5 +53,3 @@ Check out `the full documentation`_ on the github page. .. _the full documentation: https://github.com/kevin1024/pytest-httpbin - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/SOURCES.txt new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/SOURCES.txt --- old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/SOURCES.txt 2022-02-25 11:31:20.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/SOURCES.txt 2023-05-08 22:01:54.000000000 +0200 @@ -1,6 +1,7 @@ DESCRIPTION.rst MANIFEST.in README.md +pyproject.toml setup.cfg setup.py pytest_httpbin/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/requires.txt new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/requires.txt --- old/pytest-httpbin-1.0.2/pytest_httpbin.egg-info/requires.txt 2022-02-25 11:31:20.000000000 +0100 +++ new/pytest-httpbin-2.0.0/pytest_httpbin.egg-info/requires.txt 2023-05-08 22:01:54.000000000 +0200 @@ -1,6 +1,6 @@ httpbin -six [test] requests pytest +werkzeug<2.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/setup.cfg new/pytest-httpbin-2.0.0/setup.cfg --- old/pytest-httpbin-1.0.2/setup.cfg 2022-02-25 11:31:20.833808000 +0100 +++ new/pytest-httpbin-2.0.0/setup.cfg 2023-05-08 22:01:54.592055600 +0200 @@ -1,6 +1,19 @@ [bdist_wheel] universal = 1 +[flake8] +disable-noqa = True +max-line-length = 88 +extend-ignore = + E203 + +[tool:pytest] +addopts = --strict-config --strict-markers +filterwarnings = + error + ignore:ast\.(Str|NameConstant) is deprecated:DeprecationWarning:_pytest +xfail_strict = true + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/setup.py new/pytest-httpbin-2.0.0/setup.py --- old/pytest-httpbin-1.0.2/setup.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/setup.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,65 +1,59 @@ -from setuptools import setup, find_packages import codecs import os -import re +from setuptools import find_packages, setup + +__version__ = None with open("pytest_httpbin/version.py") as f: - code = compile(f.read(), "pytest_httpbin/version.py", 'exec') + code = compile(f.read(), "pytest_httpbin/version.py", "exec") exec(code) here = os.path.abspath(os.path.dirname(__file__)) # Get the long description from the relevant file -with codecs.open(os.path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f: +with codecs.open(os.path.join(here, "DESCRIPTION.rst"), encoding="utf-8") as f: long_description = f.read() setup( name="pytest-httpbin", - # There are various approaches to referencing the version. For a discussion, # see http://packaging.python.org/en/latest/tutorial.html#version version=__version__, - description="Easily test your HTTP library against a local copy of httpbin", long_description=long_description, long_description_content_type="text/x-rst", - # The project URL. - url='https://github.com/kevin1024/pytest-httpbin', - + url="https://github.com/kevin1024/pytest-httpbin", # Author details - author='Kevin McCarthy', - author_email='m...@kevinmccarthy.org', - + author="Kevin McCarthy", + author_email="m...@kevinmccarthy.org", # Choose your license - license='MIT', - + license="MIT", classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Software Development :: Testing', - 'Topic :: Software Development :: Libraries', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Testing", + "Topic :: Software Development :: Libraries", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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", ], - # What does your project relate to? - keywords='pytest-httpbin testing pytest httpbin', + keywords="pytest-httpbin testing pytest httpbin", packages=find_packages(exclude=["contrib", "docs", "tests*"]), - include_package_data = True, # include files listed in MANIFEST.in - install_requires = ['httpbin','six'], - extras_require = {"test": ["requests", "pytest"]}, - + include_package_data=True, # include files listed in MANIFEST.in + install_requires=["httpbin"], + extras_require={"test": ["requests", "pytest", "werkzeug<2.1.0"]}, + python_requires=">=3.7", # the following makes a plugin available to pytest - entry_points = { - 'pytest11': [ - 'httpbin = pytest_httpbin.plugin', + entry_points={ + "pytest11": [ + "httpbin = pytest_httpbin.plugin", ] }, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/tests/conftest.py new/pytest-httpbin-2.0.0/tests/conftest.py --- old/pytest-httpbin-1.0.2/tests/conftest.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/tests/conftest.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,8 +1,6 @@ import pytest -from pytest_httpbin.plugin import httpbin_ca_bundle - -@pytest.fixture(autouse=True, scope='function') +@pytest.fixture(autouse=True, scope="function") def httpbin_ca_bundle_autoused(httpbin_ca_bundle): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/tests/test_httpbin.py new/pytest-httpbin-2.0.0/tests/test_httpbin.py --- old/pytest-httpbin-1.0.2/tests/test_httpbin.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/tests/test_httpbin.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,5 +1,10 @@ +import ssl +import sys import unittest -import requests + +import pytest +import requests.exceptions + import pytest_httpbin @@ -8,46 +13,57 @@ def test_httpbin_accepts_get_requests(httpbin): - assert requests.get(httpbin.url + '/get').status_code == 200 + assert requests.get(httpbin.url + "/get").status_code == 200 def test_httpbin_secure_accepts_get_requests(httpbin_secure): - assert requests.get(httpbin_secure.url + '/get').status_code == 200 + assert requests.get(httpbin_secure.url + "/get").status_code == 200 def test_httpbin_secure_accepts_lots_of_get_requests(httpbin_secure): for i in range(10): - assert requests.get(httpbin_secure.url + '/get').status_code == 200 + assert requests.get(httpbin_secure.url + "/get").status_code == 200 def test_httpbin_accepts_lots_of_get_requests_in_single_session(httpbin): session = requests.Session() for i in range(10): - assert session.get(httpbin.url + '/get').status_code == 200 + assert session.get(httpbin.url + "/get").status_code == 200 def test_httpbin_both(httpbin_both): # this test will get called twice, once with an http url, once with an # https url - assert requests.get(httpbin_both.url + '/get').status_code == 200 + assert requests.get(httpbin_both.url + "/get").status_code == 200 def test_httpbin_join(httpbin): - assert httpbin.join('foo') == httpbin.url + '/foo' + assert httpbin.join("foo") == httpbin.url + "/foo" def test_httpbin_str(httpbin): - assert httpbin + '/foo' == httpbin.url + '/foo' + assert httpbin + "/foo" == httpbin.url + "/foo" + + +def test_chunked_encoding(httpbin): + assert requests.get(httpbin.url + "/stream/20").status_code == 200 + + +@pytest.mark.xfail( + condition=sys.version_info < (3, 8) and ssl.OPENSSL_VERSION_INFO >= (3, 0, 0), + reason="fails on python3.7 openssl 3+", + raises=requests.exceptions.SSLError, +) +def test_chunked_encoding_secure(httpbin_secure): + assert requests.get(httpbin_secure.url + "/stream/20").status_code == 200 -def test_chunked_encoding(httpbin_both): - assert requests.get(httpbin_both.url + '/stream/20').status_code == 200 @pytest_httpbin.use_class_based_httpbin @pytest_httpbin.use_class_based_httpbin_secure class TestClassBassedTests(unittest.TestCase): def test_http(self): - assert requests.get(self.httpbin.url + '/get').status_code == 200 + assert requests.get(self.httpbin.url + "/get").status_code == 200 def test_http_secure(self): - assert requests.get(self.httpbin_secure.url + '/get').status_code == 200 + assert requests.get(self.httpbin_secure.url + "/get").status_code == 200 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/tests/test_server.py new/pytest-httpbin-2.0.0/tests/test_server.py --- old/pytest-httpbin-1.0.2/tests/test_server.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/tests/test_server.py 2023-05-08 22:01:08.000000000 +0200 @@ -1,21 +1,22 @@ -# coding=utf8 -# -*- coding: utf8 -*- -# vim: set fileencoding=utf8 : - +import contextlib import os -import requests +import re +import socket + import pytest +import requests.exceptions +from httpbin import app as httpbin_app from util import get_raw_http_response + from pytest_httpbin import serve -from httpbin import app as httpbin_app def test_content_type_header_not_automatically_added(httpbin): """ The server was automatically adding this for some reason, see issue #5 """ - resp = requests.get(httpbin + '/headers').json()['headers'] - assert 'Content-Type' not in resp + resp = requests.get(httpbin + "/headers").json()["headers"] + assert "Content-Type" not in resp def test_unicode_data(httpbin): @@ -24,55 +25,77 @@ was binary, see issue #7 """ resp = requests.post( - httpbin + '/post', - data=u'оживлÑннÑм'.encode('utf-8'), + httpbin + "/post", + data="оживлÑннÑм".encode(), headers={ - 'content-type': 'text/html; charset=utf-8', - } + "content-type": "text/html; charset=utf-8", + }, ) - assert resp.json()['data'] == u'оживлÑннÑм' + assert resp.json()["data"] == "оживлÑннÑм" def test_server_should_be_http_1_1(httpbin): """ The server should speak HTTP/1.1 since we live in the future, see issue #6 """ - resp = get_raw_http_response(httpbin.host, httpbin.port, '/get') - assert resp.startswith(b'HTTP/1.1') + resp = get_raw_http_response(httpbin.host, httpbin.port, "/get") + assert resp.startswith(b"HTTP/1.1") + def test_dont_crash_on_certificate_problems(httpbin_secure): - with pytest.raises(Exception): + with pytest.raises(requests.exceptions.SSLError): + # this request used to hang + requests.get(httpbin_secure + "/get", verify=True, cert=__file__) + + # and this request would never happen + requests.get( + httpbin_secure + "/get", + verify=True, + ) + + +def test_dont_crash_on_handshake_timeout(httpbin_secure, capsys): + with socket.socket() as sock: + sock.connect((httpbin_secure.host, httpbin_secure.port)) # this request used to hang - requests.get( - httpbin_secure + '/get', - verify = True, - cert=__file__ + assert sock.recv(1) == b"" + + assert ( + re.match( + r"pytest-httpbin server hit an exception serving request: .* The " + "handshake operation timed out\nattempting to ignore so the rest " + "of the tests can run\n", + capsys.readouterr().out, ) + is not None + ) + # and this request would never happen requests.get( - httpbin_secure + '/get', - verify = True, + httpbin_secure + "/get", + verify=True, ) -@pytest.mark.parametrize('protocol', ('http', 'https')) +@pytest.mark.parametrize("protocol", ("http", "https")) def test_fixed_port_environment_variables(protocol): """ Note that we cannot test the fixture here because it is session scoped and was already started. Thus, let's just test a new Server instance. """ - if protocol == 'http': + if protocol == "http": server_cls = serve.Server - envvar = 'HTTPBIN_HTTP_PORT' - elif protocol == 'https': + envvar = "HTTPBIN_HTTP_PORT" + elif protocol == "https": server_cls = serve.SecureServer - envvar = 'HTTPBIN_HTTPS_PORT' + envvar = "HTTPBIN_HTTPS_PORT" else: - raise RuntimeError('Unexpected protocol param: {0}'.format(protocol)) + raise RuntimeError(f"Unexpected protocol param: {protocol}") # just have different port to avoid adrress already in use # if the second test run too fast after the first one (happens on pypy) port = 12345 + len(protocol) + server = contextlib.nullcontext() try: envvar_original = os.environ.get(envvar, None) @@ -81,10 +104,7 @@ assert server.port == port finally: # if we don't do this, it blocks: - try: - server.start() - server.stop() - except UnboundLocalError: + with server: pass # restore the original environ: @@ -95,11 +115,10 @@ def test_redirect_location_is_https_for_secure_server(httpbin_secure): - assert httpbin_secure.url.startswith('https://') + assert httpbin_secure.url.startswith("https://") response = requests.get( - httpbin_secure + "/redirect-to?url=/html", - allow_redirects=False + httpbin_secure + "/redirect-to?url=/html", allow_redirects=False ) assert response.status_code == 302 - assert response.headers.get('Location') - assert response.headers['Location'].startswith('https://') + assert response.headers.get("Location") + assert response.headers["Location"] == "/html" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-httpbin-1.0.2/tests/util.py new/pytest-httpbin-2.0.0/tests/util.py --- old/pytest-httpbin-1.0.2/tests/util.py 2022-02-25 11:28:09.000000000 +0100 +++ new/pytest-httpbin-2.0.0/tests/util.py 2023-05-08 22:01:08.000000000 +0200 @@ -2,29 +2,28 @@ def get_raw_http_response(host, port, path): - CRLF = b"\r\n" request = [ - b"GET " + path.encode('ascii') + b" HTTP/1.1", - b"Host: " + host.encode('ascii'), + b"GET " + path.encode("ascii") + b" HTTP/1.1", + b"Host: " + host.encode("ascii"), b"Connection: Close", b"", b"", ] # Connect to the server - s = socket.socket() - s.connect((host, port)) + with socket.socket() as s: + s.connect((host, port)) - # Send an HTTP request - s.send(CRLF.join(request)) + # Send an HTTP request + s.send(CRLF.join(request)) - # Get the response (in several parts, if necessary) - response = b'' - buffer = s.recv(4096) - while buffer: - response += buffer + # Get the response (in several parts, if necessary) + response = b"" buffer = s.recv(4096) + while buffer: + response += buffer + buffer = s.recv(4096) - return response + return response