From 005c8596cb94d2444fafc3be8b6f233ccda75ab4 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Sat, 16 Mar 2024 16:29:27 +0000 Subject: [PATCH 1/6] get rid of six and python 2 --- README.rst | 18 ++++------ setup.py | 8 ++--- tox.ini | 4 +-- wsgi_intercept/__init__.py | 27 +++++---------- wsgi_intercept/_urllib3.py | 33 ++++++++++++++----- wsgi_intercept/interceptor.py | 2 +- wsgi_intercept/tests/test_interceptor.py | 10 ++---- wsgi_intercept/tests/test_response_headers.py | 6 +--- wsgi_intercept/urllib3_intercept.py | 3 -- 9 files changed, 48 insertions(+), 63 deletions(-) diff --git a/README.rst b/README.rst index c535d64..750a4e3 100644 --- a/README.rst +++ b/README.rst @@ -13,8 +13,8 @@ threads to test your Web app. Supported Libaries ================== -``wsgi_intercept`` works with a variety of HTTP clients in Python 2.7, -3.5 and beyond, and in pypy. +``wsgi_intercept`` works with a variety of HTTP clients in Python 3.7 +and beyond, and in pypy. * urllib2 * urllib.request @@ -22,7 +22,7 @@ Supported Libaries * http.client * httplib2 * requests -* urllib3 (<2.0.0, urllib3 2 support is in progress) +* urllib3 How Does It Work? ================= @@ -88,14 +88,9 @@ Packages Intercepted Unfortunately each of the HTTP client libraries use their own specific mechanism for making HTTP call-outs, so individual implementations are needed. At this time there are implementations for ``httplib2``, -``urllib3`` (<2.0.0) and ``requests`` in both Python 2 and 3, ``urllib2`` and -``httplib`` in Python 2 and ``urllib.request`` and ``http.client`` +``urllib3``, ``requests``, ``urllib.request``, and ``http.client`` in Python 3. -If you are using Python 2 and need support for a different HTTP -client, require a version of ``wsgi_intercept<0.6``. Earlier versions -include support for ``webtest``, ``webunit`` and ``zope.testbrowser``. - The best way to figure out how to use interception is to inspect `the tests`_. More comprehensive documentation available upon request. @@ -115,9 +110,8 @@ it into all of the *other* Python Web testing frameworks. The Python 2 version of wsgi-intercept was the result. Kumar McMillan later took over maintenance. -The current version is tested with Python 2.7, 3.5-3.11, and pypy and pypy3. -It was assembled by `Chris Dent`_. Testing and documentation improvements -from `Sasha Hart`_. +The current version is tested with Python 3.7-3.12, and pypy3. It was assembled +by `Chris Dent`_. Testing and documentation improvements from `Sasha Hart`_. .. _"best Web testing framework": http://blog.ianbicking.org/best-of-the-web-app-test-frameworks.html diff --git a/setup.py b/setup.py index 6a1c3b4..d4ccb7c 100644 --- a/setup.py +++ b/setup.py @@ -8,8 +8,6 @@ Intended Audience :: Developers License :: OSI Approved :: MIT License Operating System :: OS Independent -Programming Language :: Python :: 2 -Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 @@ -36,15 +34,13 @@ 'license': 'MIT License', 'classifiers': CLASSIFIERS, 'packages': find_packages(), - 'install_requires': [ - 'six', - ], + 'python_requires': '>=3', 'extras_require': { 'testing': [ 'pytest>=2.4', 'httplib2', 'requests>=2.0.1', - 'urllib3>=1.11.0,<2.0.0', + 'urllib3<2.0.0', ], 'docs': [ 'sphinx', diff --git a/tox.ini b/tox.ini index a7e7143..75ae60a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,11 @@ [tox] minversion = 1.6 skipsdist = True -envlist = py27,py35,py36,py37,py38,py39,py310,py311,py312,pypy,pep8,docs,readme +envlist = py37,py38,py39,py310,py311,py312,pypy,pep8,docs,readme [testenv] deps = .[testing] -commands = py.test --tb=short wsgi_intercept/tests +commands = py.test --tb=short wsgi_intercept/tests {posargs} passenv = WSGI_INTERCEPT_* [testenv:pep8] diff --git a/wsgi_intercept/__init__.py b/wsgi_intercept/__init__.py index ec9397f..a3e62e9 100644 --- a/wsgi_intercept/__init__.py +++ b/wsgi_intercept/__init__.py @@ -144,15 +144,9 @@ def load_app(): import traceback from io import BytesIO -# Don't use six here because it is unquote_to_bytes that we want in -# Python 3. -try: - from urllib.parse import unquote_to_bytes as url_unquote -except ImportError: - from urllib import unquote as url_unquote +from urllib.parse import unquote_to_bytes as url_unquote -import six -from six.moves.http_client import HTTPConnection, HTTPSConnection +from http.client import HTTPConnection, HTTPSConnection # Set this to True to cause response headers from the intercepted @@ -227,8 +221,7 @@ def make_environ(inp, host, port, script_name): environ = {} method_line = inp.readline() - if six.PY3: - method_line = method_line.decode('ISO-8859-1') + method_line = method_line.decode('ISO-8859-1') content_type = None content_length = None @@ -302,13 +295,11 @@ def make_environ(inp, host, port, script_name): # fill out our dictionary. # - # In Python3 turn the bytes of the path info into a string of - # latin-1 code points, because that's what the spec says we must - # do to be like a server. Later various libraries will be forced - # to decode and then reencode to get the UTF-8 that everyone - # wants. - if six.PY3: - path_info = path_info.decode('latin-1') + # Turn the bytes of the path info into a string of latin-1 code points, + # because that's what the spec says we must do to be like a server. Later + # various libraries will be forced to decode and then reencode to get the + # UTF-8 that everyone wants. + path_info = path_info.decode('latin-1') environ.update({ "wsgi.version": (1, 0), @@ -633,7 +624,7 @@ def connect(self): else: self._context.verify_mode = ssl.VerifyMode[ self.cert_reqs] - elif isinstance(self.cert_reqs, six.string_types): + elif isinstance(self.cert_reqs, str): # Support for Python3.5 and below self._context.verify_mode = getattr(ssl, self.cert_reqs, diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index 969ddac..417c387 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -8,16 +8,32 @@ wsgi_fake_socket.settimeout = lambda self, timeout: None +HTTP_KEYWORD_POPS = [ + 'strict', + 'socket_options', + 'server_hostname', +] + +HTTPS_KEYWORD_POPS = HTTP_KEYWORD_POPS + [ + 'key_password', + 'server_hostname', + 'cert_reqs', + 'ca_certs', + 'ca_cert_dir', + 'assert_hostname', + 'assert_fingerprint', + 'ssl_version', + 'ssl_minimum_version', + 'ssl_maximum_version', +] def make_urllib3_override(HTTPConnectionPool, HTTPSConnectionPool, HTTPConnection, HTTPSConnection): class HTTP_WSGIInterceptor(WSGI_HTTPConnection, HTTPConnection): def __init__(self, *args, **kwargs): - if 'strict' in kwargs and sys.version_info > (3, 0): - kwargs.pop('strict') - kwargs.pop('socket_options', None) - kwargs.pop('server_hostname', None) + for kw in HTTP_KEYWORD_POPS: + kwargs.pop(kw, None) WSGI_HTTPConnection.__init__(self, *args, **kwargs) HTTPConnection.__init__(self, *args, **kwargs) @@ -25,14 +41,13 @@ class HTTPS_WSGIInterceptor(WSGI_HTTPSConnection, HTTPSConnection): is_verified = True def __init__(self, *args, **kwargs): - if 'strict' in kwargs and sys.version_info > (3, 0): - kwargs.pop('strict') - kwargs.pop('socket_options', None) - kwargs.pop('key_password', None) - kwargs.pop('server_hostname', None) + print(f"pre: {args} ::: {kwargs}") + for kw in HTTPS_KEYWORD_POPS: + kwargs.pop(kw, None) if sys.version_info > (3, 12): kwargs.pop('key_file', None) kwargs.pop('cert_file', None) + print(f"post: {args} ::: {kwargs}") WSGI_HTTPSConnection.__init__(self, *args, **kwargs) HTTPSConnection.__init__(self, *args, **kwargs) diff --git a/wsgi_intercept/interceptor.py b/wsgi_intercept/interceptor.py index 2d2d581..a6f5baa 100644 --- a/wsgi_intercept/interceptor.py +++ b/wsgi_intercept/interceptor.py @@ -4,7 +4,7 @@ from importlib import import_module from uuid import uuid4 -from six.moves.urllib import parse as urlparse +from urllib import parse as urlparse import wsgi_intercept diff --git a/wsgi_intercept/tests/test_interceptor.py b/wsgi_intercept/tests/test_interceptor.py index f3dd2f0..28eab42 100644 --- a/wsgi_intercept/tests/test_interceptor.py +++ b/wsgi_intercept/tests/test_interceptor.py @@ -11,13 +11,9 @@ import requests import urllib3 from httplib2 import Http, ServerNotFoundError -# don't use six as the monkey patching gets confused -try: - import http.client as http_client -except ImportError: - import httplib as http_client -from six.moves.urllib.request import urlopen -from six.moves.urllib.error import URLError +import http.client as http_client +from urllib.request import urlopen +from urllib.error import URLError from wsgi_intercept.interceptor import ( Interceptor, HttpClientInterceptor, Httplib2Interceptor, diff --git a/wsgi_intercept/tests/test_response_headers.py b/wsgi_intercept/tests/test_response_headers.py index 8970555..19685f9 100644 --- a/wsgi_intercept/tests/test_response_headers.py +++ b/wsgi_intercept/tests/test_response_headers.py @@ -10,7 +10,6 @@ import pytest import requests -import six import wsgi_intercept from wsgi_intercept.interceptor import RequestsInterceptor @@ -56,10 +55,7 @@ def header_app(): def test_encoding_violation(): """If the header is unicode we expect boom.""" header_key = 'request-id' - if six.PY2: - header_value = u'alpha' - else: - header_value = b'alpha' + header_value = b'alpha' # we expect our http library to give us a str returned_header = 'alpha' diff --git a/wsgi_intercept/urllib3_intercept.py b/wsgi_intercept/urllib3_intercept.py index d4e82e3..eff3997 100644 --- a/wsgi_intercept/urllib3_intercept.py +++ b/wsgi_intercept/urllib3_intercept.py @@ -1,8 +1,5 @@ """Intercept HTTP connections that use `urllib3 `_. - -Note that currently only urllib3 <2.0.0 is supported. 2.0.0 support -is in progress. """ from urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool From 723a16aae0c2564036bd92f1f815eba8d9cc2611 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Tue, 19 Mar 2024 19:20:29 +0000 Subject: [PATCH 2/6] for sharing testing --- setup.py | 2 +- wsgi_intercept/__init__.py | 5 +++++ wsgi_intercept/_urllib3.py | 11 ++++++++--- wsgi_intercept/tests/test_urllib3.py | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index d4ccb7c..a185927 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,7 @@ 'pytest>=2.4', 'httplib2', 'requests>=2.0.1', - 'urllib3<2.0.0', + 'urllib3>=2.0.0', ], 'docs': [ 'sphinx', diff --git a/wsgi_intercept/__init__.py b/wsgi_intercept/__init__.py index a3e62e9..3009115 100644 --- a/wsgi_intercept/__init__.py +++ b/wsgi_intercept/__init__.py @@ -578,6 +578,11 @@ class WSGI_HTTPSConnection(HTTPSConnection, WSGI_HTTPConnection): Intercept all traffic to certain hosts & redirect into a WSGI application object. """ + + def __init__(self, *args, **kwargs): + print("getting %s ::: %s" % (args, kwargs)) + super().__init__(*args, **kwargs) + def get_app(self, host, port): """ Return the app object for the given (host, port). diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index 417c387..a7889ae 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -32,6 +32,7 @@ def make_urllib3_override(HTTPConnectionPool, HTTPSConnectionPool, class HTTP_WSGIInterceptor(WSGI_HTTPConnection, HTTPConnection): def __init__(self, *args, **kwargs): + print(f"http pre: {args} ::: {kwargs}") for kw in HTTP_KEYWORD_POPS: kwargs.pop(kw, None) WSGI_HTTPConnection.__init__(self, *args, **kwargs) @@ -41,15 +42,19 @@ class HTTPS_WSGIInterceptor(WSGI_HTTPSConnection, HTTPSConnection): is_verified = True def __init__(self, *args, **kwargs): - print(f"pre: {args} ::: {kwargs}") + print(f"https pre: {args} ::: {kwargs}") for kw in HTTPS_KEYWORD_POPS: kwargs.pop(kw, None) if sys.version_info > (3, 12): kwargs.pop('key_file', None) kwargs.pop('cert_file', None) - print(f"post: {args} ::: {kwargs}") - WSGI_HTTPSConnection.__init__(self, *args, **kwargs) + print(f"https post: {args} ::: {kwargs}") + host = kwargs.pop('host') + port = kwargs.pop('port') + WSGI_HTTPSConnection.__init__(self, host, port, *args, **kwargs) + print("after wsgi") HTTPSConnection.__init__(self, *args, **kwargs) + print("after https") def install(): if 'http_proxy' in os.environ or 'https_proxy' in os.environ: diff --git a/wsgi_intercept/tests/test_urllib3.py b/wsgi_intercept/tests/test_urllib3.py index d99b929..b2a7185 100644 --- a/wsgi_intercept/tests/test_urllib3.py +++ b/wsgi_intercept/tests/test_urllib3.py @@ -54,7 +54,7 @@ def test_proxy_handling(): del os.environ['http_proxy'] -def test_https(): +def test_https_meo(): with InstalledApp(wsgi_app.simple_app, host=HOST, port=443) as app: resp = http.request( 'GET', 'https://some_hopefully_nonexistant_domain:443/') From 02694bd3ad681ed49319b277b33eff15eb30bac6 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Tue, 19 Mar 2024 20:44:40 +0000 Subject: [PATCH 3/6] play around with arg manipulation --- wsgi_intercept/__init__.py | 20 +++++++++++++++++--- wsgi_intercept/_urllib3.py | 10 ++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/wsgi_intercept/__init__.py b/wsgi_intercept/__init__.py index 3009115..8042205 100644 --- a/wsgi_intercept/__init__.py +++ b/wsgi_intercept/__init__.py @@ -526,6 +526,23 @@ class WSGI_HTTPConnection(HTTPConnection): Intercept all traffic to certain hosts & redirect into a WSGI application object. """ + + def __init__(self, *args, **kwargs): + print(f"args1 is {args}, kwargs is {kwargs}") + if 'host' in kwargs: + host = kwargs.pop('host') + if 'port' in kwargs: + port = kwargs.pop('port') + else: + port = None + print(f"args2 is {args}, kwargs is {kwargs}") + super().__init__(host, port, *args, **kwargs) + else: + if len(args) > 2: + args = args[0:2] + super().__init__(*args, **kwargs) + + def get_app(self, host, port): """ Return the app object for the given (host, port). @@ -579,9 +596,6 @@ class WSGI_HTTPSConnection(HTTPSConnection, WSGI_HTTPConnection): application object. """ - def __init__(self, *args, **kwargs): - print("getting %s ::: %s" % (args, kwargs)) - super().__init__(*args, **kwargs) def get_app(self, host, port): """ diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index a7889ae..9b05cf4 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -32,7 +32,6 @@ def make_urllib3_override(HTTPConnectionPool, HTTPSConnectionPool, class HTTP_WSGIInterceptor(WSGI_HTTPConnection, HTTPConnection): def __init__(self, *args, **kwargs): - print(f"http pre: {args} ::: {kwargs}") for kw in HTTP_KEYWORD_POPS: kwargs.pop(kw, None) WSGI_HTTPConnection.__init__(self, *args, **kwargs) @@ -42,19 +41,14 @@ class HTTPS_WSGIInterceptor(WSGI_HTTPSConnection, HTTPSConnection): is_verified = True def __init__(self, *args, **kwargs): - print(f"https pre: {args} ::: {kwargs}") + print(f"{args}:::{kwargs}") for kw in HTTPS_KEYWORD_POPS: kwargs.pop(kw, None) if sys.version_info > (3, 12): kwargs.pop('key_file', None) kwargs.pop('cert_file', None) - print(f"https post: {args} ::: {kwargs}") - host = kwargs.pop('host') - port = kwargs.pop('port') - WSGI_HTTPSConnection.__init__(self, host, port, *args, **kwargs) - print("after wsgi") + WSGI_HTTPSConnection.__init__(self, *args, **kwargs) HTTPSConnection.__init__(self, *args, **kwargs) - print("after https") def install(): if 'http_proxy' in os.environ or 'https_proxy' in os.environ: From 8c6407647514ceced688a89e16125415c87bb463 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Wed, 20 Mar 2024 21:47:23 +0000 Subject: [PATCH 4/6] Correct SSL handling for urllib3 based things It seems that we need to replicate some ssl context handling done in urllib3 as we are routing around some of that by using wsgi-intercept, even when not actively intercepting a host. --- wsgi_intercept/__init__.py | 30 +++++++++++++++++++++--------- wsgi_intercept/_urllib3.py | 2 ++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/wsgi_intercept/__init__.py b/wsgi_intercept/__init__.py index 8042205..3592751 100644 --- a/wsgi_intercept/__init__.py +++ b/wsgi_intercept/__init__.py @@ -528,14 +528,18 @@ class WSGI_HTTPConnection(HTTPConnection): """ def __init__(self, *args, **kwargs): - print(f"args1 is {args}, kwargs is {kwargs}") + """ + Do a complex dance to deal with urllib3's method signature + constraints. + """ + # TODO: This seems really really fragile but is passing + # tests. if 'host' in kwargs: host = kwargs.pop('host') if 'port' in kwargs: port = kwargs.pop('port') else: port = None - print(f"args2 is {args}, kwargs is {kwargs}") super().__init__(host, port, *args, **kwargs) else: if len(args) > 2: @@ -634,22 +638,31 @@ def connect(self): try: import ssl if hasattr(self, '_context'): + # Extract cert_reqs from requests + urllib3. + # They do some of their own SSL context management + # that wsgi intercept routes around, so we need to + # be careful. + if hasattr(self, '_intercept_cert_reqs'): + cert_reqs = self._intercept_cert_reqs + else: + cert_reqs = self.cert_reqs + self._context.check_hostname = self.assert_hostname self._check_hostname = self.assert_hostname # Py3.6 if hasattr(ssl, 'VerifyMode'): # Support for Python3.6 and higher - if isinstance(self.cert_reqs, ssl.VerifyMode): - self._context.verify_mode = self.cert_reqs + if isinstance(cert_reqs, ssl.VerifyMode): + self._context.verify_mode = cert_reqs else: self._context.verify_mode = ssl.VerifyMode[ - self.cert_reqs] - elif isinstance(self.cert_reqs, str): + cert_reqs] + elif isinstance(cert_reqs, str): # Support for Python3.5 and below self._context.verify_mode = getattr(ssl, - self.cert_reqs, + cert_reqs, self._context.verify_mode) else: - self._context.verify_mode = self.cert_reqs + self._context.verify_mode = cert_reqs if not hasattr(self, 'key_file'): self.key_file = None @@ -668,7 +681,6 @@ def connect(self): else: self._check_hostname = self.check_hostname except (ImportError, AttributeError): - import traceback traceback.print_exc() HTTPSConnection.connect(self) diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index 9b05cf4..a67bda0 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -42,6 +42,8 @@ class HTTPS_WSGIInterceptor(WSGI_HTTPSConnection, HTTPSConnection): def __init__(self, *args, **kwargs): print(f"{args}:::{kwargs}") + if 'cert_reqs' in kwargs and kwargs['cert_reqs'] is not None: + self._intercept_cert_reqs = kwargs.pop("cert_reqs") for kw in HTTPS_KEYWORD_POPS: kwargs.pop(kw, None) if sys.version_info > (3, 12): From dd4107f9f036a283337853c832f03f6a761e551e Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Wed, 20 Mar 2024 21:59:39 +0000 Subject: [PATCH 5/6] pep8 and readme fixes --- README.rst | 7 ++++--- wsgi_intercept/__init__.py | 21 +++++++------------- wsgi_intercept/_urllib3.py | 1 + wsgi_intercept/http_client_intercept.py | 19 +++++------------- wsgi_intercept/tests/test_http_client.py | 5 +---- wsgi_intercept/tests/test_urllib.py | 5 +---- wsgi_intercept/tests/test_urllib3.py | 2 +- wsgi_intercept/tests/test_wsgi_compliance.py | 5 +---- wsgi_intercept/tests/wsgi_app.py | 5 ----- wsgi_intercept/urllib_intercept.py | 5 +---- 10 files changed, 22 insertions(+), 53 deletions(-) diff --git a/README.rst b/README.rst index 750a4e3..3cea98e 100644 --- a/README.rst +++ b/README.rst @@ -88,7 +88,7 @@ Packages Intercepted Unfortunately each of the HTTP client libraries use their own specific mechanism for making HTTP call-outs, so individual implementations are needed. At this time there are implementations for ``httplib2``, -``urllib3``, ``requests``, ``urllib.request``, and ``http.client`` +``urllib3``, ``requests``, ``urllib.request`` and ``http.client`` in Python 3. The best way to figure out how to use interception is to inspect @@ -110,8 +110,9 @@ it into all of the *other* Python Web testing frameworks. The Python 2 version of wsgi-intercept was the result. Kumar McMillan later took over maintenance. -The current version is tested with Python 3.7-3.12, and pypy3. It was assembled -by `Chris Dent`_. Testing and documentation improvements from `Sasha Hart`_. +The current version is tested with Python 3.7-3.12, and pypy3. It was +assembled by `Chris Dent`_. Testing and documentation improvements from +`Sasha Hart`_. .. _"best Web testing framework": http://blog.ianbicking.org/best-of-the-web-app-test-frameworks.html diff --git a/wsgi_intercept/__init__.py b/wsgi_intercept/__init__.py index 3592751..c32ce1e 100644 --- a/wsgi_intercept/__init__.py +++ b/wsgi_intercept/__init__.py @@ -13,8 +13,8 @@ Supported Libaries ================== -``wsgi_intercept`` works with a variety of HTTP clients in Python 2.7, -3.7 and beyond, and in pypy. +``wsgi_intercept`` works with a variety of HTTP clients in Python 3.7 +and beyond, and in pypy. * urllib2 * urllib.request @@ -22,7 +22,7 @@ * http.client * httplib2 * requests -* urllib3 (<2.0.0, urllib3 2 support is in progress) +* urllib3 How Does It Work? ================= @@ -88,14 +88,9 @@ def load_app(): Unfortunately each of the HTTP client libraries use their own specific mechanism for making HTTP call-outs, so individual implementations are needed. At this time there are implementations for ``httplib2``, -``urllib3`` (<2.0.0) and ``requests`` in both Python 2 and 3, ``urllib2`` and -``httplib`` in Python 2 and ``urllib.request`` and ``http.client`` +``urllib3``, ``requests``, ``urllib.request`` and ``http.client`` in Python 3. -If you are using Python 2 and need support for a different HTTP -client, require a version of ``wsgi_intercept<0.6``. Earlier versions -include support for ``webtest``, ``webunit`` and ``zope.testbrowser``. - The best way to figure out how to use interception is to inspect `the tests`_. More comprehensive documentation available upon request. @@ -115,9 +110,9 @@ def load_app(): The Python 2 version of wsgi-intercept was the result. Kumar McMillan later took over maintenance. -The current version is tested with Python 2.7, 3.5-3.11, and pypy and pypy3. -It was assembled by `Chris Dent`_. Testing and documentation improvements -from `Sasha Hart`_. +The current version is tested with Python 3.7-3.12, and pypy3. It was +assembled by `Chris Dent`_. Testing and documentation improvements from +`Sasha Hart`_. .. _"best Web testing framework": http://blog.ianbicking.org/best-of-the-web-app-test-frameworks.html @@ -546,7 +541,6 @@ def __init__(self, *args, **kwargs): args = args[0:2] super().__init__(*args, **kwargs) - def get_app(self, host, port): """ Return the app object for the given (host, port). @@ -600,7 +594,6 @@ class WSGI_HTTPSConnection(HTTPSConnection, WSGI_HTTPConnection): application object. """ - def get_app(self, host, port): """ Return the app object for the given (host, port). diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index a67bda0..c6b82c1 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -27,6 +27,7 @@ 'ssl_maximum_version', ] + def make_urllib3_override(HTTPConnectionPool, HTTPSConnectionPool, HTTPConnection, HTTPSConnection): diff --git a/wsgi_intercept/http_client_intercept.py b/wsgi_intercept/http_client_intercept.py index 56d930c..7f86b0b 100644 --- a/wsgi_intercept/http_client_intercept.py +++ b/wsgi_intercept/http_client_intercept.py @@ -1,23 +1,14 @@ """Intercept HTTP connections that use httplib (Py2) or http.client (Py3). """ -try: - import http.client as http_lib -except ImportError: - import httplib as http_lib +import http.client as http_lib from . import WSGI_HTTPConnection, WSGI_HTTPSConnection -try: - from http.client import ( - HTTPConnection as OriginalHTTPConnection, - HTTPSConnection as OriginalHTTPSConnection - ) -except ImportError: - from httplib import ( - HTTPConnection as OriginalHTTPConnection, - HTTPSConnection as OriginalHTTPSConnection - ) +from http.client import ( + HTTPConnection as OriginalHTTPConnection, + HTTPSConnection as OriginalHTTPSConnection +) class HTTP_WSGIInterceptor(WSGI_HTTPConnection, http_lib.HTTPConnection): diff --git a/wsgi_intercept/tests/test_http_client.py b/wsgi_intercept/tests/test_http_client.py index f33f4c7..d2f9a96 100644 --- a/wsgi_intercept/tests/test_http_client.py +++ b/wsgi_intercept/tests/test_http_client.py @@ -2,10 +2,7 @@ from wsgi_intercept import http_client_intercept, WSGIAppError from . import wsgi_app from .install import installer_class, skipnetwork -try: - import http.client as http_lib -except ImportError: - import httplib as http_lib +import http.client as http_lib HOST = 'some_hopefully_nonexistant_domain' diff --git a/wsgi_intercept/tests/test_urllib.py b/wsgi_intercept/tests/test_urllib.py index 9b1df03..ba9a486 100644 --- a/wsgi_intercept/tests/test_urllib.py +++ b/wsgi_intercept/tests/test_urllib.py @@ -3,10 +3,7 @@ from wsgi_intercept import urllib_intercept, WSGIAppError from . import wsgi_app from .install import installer_class, skipnetwork -try: - import urllib.request as url_lib -except ImportError: - import urllib2 as url_lib +import urllib.request as url_lib HOST = 'some_hopefully_nonexistant_domain' diff --git a/wsgi_intercept/tests/test_urllib3.py b/wsgi_intercept/tests/test_urllib3.py index b2a7185..d99b929 100644 --- a/wsgi_intercept/tests/test_urllib3.py +++ b/wsgi_intercept/tests/test_urllib3.py @@ -54,7 +54,7 @@ def test_proxy_handling(): del os.environ['http_proxy'] -def test_https_meo(): +def test_https(): with InstalledApp(wsgi_app.simple_app, host=HOST, port=443) as app: resp = http.request( 'GET', 'https://some_hopefully_nonexistant_domain:443/') diff --git a/wsgi_intercept/tests/test_wsgi_compliance.py b/wsgi_intercept/tests/test_wsgi_compliance.py index 39ee12b..89f73d2 100644 --- a/wsgi_intercept/tests/test_wsgi_compliance.py +++ b/wsgi_intercept/tests/test_wsgi_compliance.py @@ -1,9 +1,6 @@ import sys import pytest -try: - from urllib.parse import unquote -except ImportError: - from urllib import unquote +from urllib.parse import unquote from wsgi_intercept import httplib2_intercept from . import wsgi_app from .install import installer_class diff --git a/wsgi_intercept/tests/wsgi_app.py b/wsgi_intercept/tests/wsgi_app.py index 9761bbb..0c573dc 100644 --- a/wsgi_intercept/tests/wsgi_app.py +++ b/wsgi_intercept/tests/wsgi_app.py @@ -4,11 +4,6 @@ from pprint import pformat -try: - bytes -except ImportError: - bytes = str - def simple_app(environ, start_response): """Simplest possible application object""" diff --git a/wsgi_intercept/urllib_intercept.py b/wsgi_intercept/urllib_intercept.py index 2454d5c..fa0697c 100644 --- a/wsgi_intercept/urllib_intercept.py +++ b/wsgi_intercept/urllib_intercept.py @@ -4,10 +4,7 @@ import os -try: - import urllib.request as url_lib -except ImportError: - import urllib2 as url_lib +import urllib.request as url_lib from . import WSGI_HTTPConnection, WSGI_HTTPSConnection From 1bd1d375a0c977b5994f62c4a2747f1053b64faa Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Fri, 22 Mar 2024 10:57:36 +0000 Subject: [PATCH 6/6] extraneous print removal --- wsgi_intercept/_urllib3.py | 1 - 1 file changed, 1 deletion(-) diff --git a/wsgi_intercept/_urllib3.py b/wsgi_intercept/_urllib3.py index c6b82c1..f757541 100644 --- a/wsgi_intercept/_urllib3.py +++ b/wsgi_intercept/_urllib3.py @@ -42,7 +42,6 @@ class HTTPS_WSGIInterceptor(WSGI_HTTPSConnection, HTTPSConnection): is_verified = True def __init__(self, *args, **kwargs): - print(f"{args}:::{kwargs}") if 'cert_reqs' in kwargs and kwargs['cert_reqs'] is not None: self._intercept_cert_reqs = kwargs.pop("cert_reqs") for kw in HTTPS_KEYWORD_POPS: