Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-httpx for openSUSE:Factory 
checked in at 2023-10-26 17:11:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-httpx (Old)
 and      /work/SRC/openSUSE:Factory/.python-httpx.new.24901 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-httpx"

Thu Oct 26 17:11:48 2023 rev:11 rq:1120298 version:0.25.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-httpx/python-httpx.changes        
2023-09-12 21:02:37.139609768 +0200
+++ /work/SRC/openSUSE:Factory/.python-httpx.new.24901/python-httpx.changes     
2023-10-26 17:11:53.418696672 +0200
@@ -1,0 +2,21 @@
+Fri Oct 20 21:52:56 UTC 2023 - Matej Cepl <mc...@cepl.eu>
+
+- Update to 0.25.0:
+  - Drop support for Python 3.7.
+  - Support HTTPS proxies.
+  - Change the type of Extensions from Mapping[Str, Any] to
+    MutableMapping[Str, Any].
+  - Add socket_options argument to httpx.HTTPTransport and
+    httpx.AsyncHTTPTransport classes.
+  - The Response.raise_for_status() method now returns
+    the response instance. For example: data =
+    httpx.get('...').raise_for_status().json().
+  - Return 500 error response instead of exceptions when
+    raise_app_exceptions=False is set on ASGITransport.
+  - Ensure all WSGITransport environs have a SERVER_PROTOCOL.
+  - Always encode forward slashes as %2F in query parameters
+  - Use Mozilla documentation instead of httpstatuses.com for
+    HTTP error reference
+- Requires higher version of httpcore.
+
+-------------------------------------------------------------------

Old:
----
  httpx-0.24.1.tar.gz

New:
----
  httpx-0.25.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-httpx.spec ++++++
--- /var/tmp/diff_new_pack.KXq9Sx/_old  2023-10-26 17:11:54.010718415 +0200
+++ /var/tmp/diff_new_pack.KXq9Sx/_new  2023-10-26 17:11:54.010718415 +0200
@@ -27,7 +27,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-httpx%{psuffix}
-Version:        0.24.1
+Version:        0.25.0
 Release:        0
 Summary:        Python HTTP client with async support
 License:        BSD-3-Clause
@@ -43,7 +43,7 @@
 Requires:       python-certifi
 Requires:       python-idna >= 2.0
 Requires:       python-sniffio
-Requires:       (python-httpcore >= 0.17.2 with python-httpcore < 0.18.0)
+Requires:       (python-httpcore >= 0.18.0 with python-httpcore < 0.19.0)
 Recommends:     python-Brotli
 Recommends:     python-Pygments >= 2
 Recommends:     python-click >= 8

++++++ httpx-0.24.1.tar.gz -> httpx-0.25.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/.github/workflows/publish.yml 
new/httpx-0.25.0/.github/workflows/publish.yml
--- old/httpx-0.24.1/.github/workflows/publish.yml      2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/.github/workflows/publish.yml      2023-09-11 
12:13:24.000000000 +0200
@@ -17,7 +17,7 @@
       - uses: "actions/checkout@v3"
       - uses: "actions/setup-python@v4"
         with:
-          python-version: 3.7
+          python-version: 3.8
       - name: "Install dependencies"
         run: "scripts/install"
       - name: "Build package & docs"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/.github/workflows/test-suite.yml 
new/httpx-0.25.0/.github/workflows/test-suite.yml
--- old/httpx-0.24.1/.github/workflows/test-suite.yml   2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/.github/workflows/test-suite.yml   2023-09-11 
12:13:24.000000000 +0200
@@ -14,7 +14,7 @@
 
     strategy:
       matrix:
-        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
+        python-version: ["3.8", "3.9", "3.10", "3.11"]
 
     steps:
       - uses: "actions/checkout@v3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/CHANGELOG.md 
new/httpx-0.25.0/CHANGELOG.md
--- old/httpx-0.24.1/CHANGELOG.md       2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/CHANGELOG.md       2023-09-11 12:13:24.000000000 +0200
@@ -4,6 +4,26 @@
 
 The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/).
 
+## 0.25.0 (11th Sep, 2023)
+
+### Removed
+
+* Drop support for Python 3.7. (#2813)
+
+### Added
+
+* Support HTTPS proxies. (#2845)
+* Change the type of `Extensions` from `Mapping[Str, Any]` to 
`MutableMapping[Str, Any]`. (#2803)
+* Add `socket_options` argument to `httpx.HTTPTransport` and 
`httpx.AsyncHTTPTransport` classes. (#2716)
+* The `Response.raise_for_status()` method now returns the response instance. 
For example: `data = httpx.get('...').raise_for_status().json()`. (#2776)
+
+### Fixed
+
+* Return `500` error response instead of exceptions when 
`raise_app_exceptions=False` is set on `ASGITransport`. (#2669)
+* Ensure all `WSGITransport` environs have a `SERVER_PROTOCOL`. (#2708)
+* Always encode forward slashes as `%2F` in query parameters (#2723)
+* Use Mozilla documentation instead of `httpstatuses.com` for HTTP error 
reference (#2768)
+
 ## 0.24.1 (17th May, 2023)
 
 ### Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/README.md new/httpx-0.25.0/README.md
--- old/httpx-0.24.1/README.md  2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/README.md  2023-09-11 12:13:24.000000000 +0200
@@ -103,7 +103,7 @@
 $ pip install httpx[http2]
 ```
 
-HTTPX requires Python 3.7+.
+HTTPX requires Python 3.8+.
 
 ## Documentation
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/README_chinese.md 
new/httpx-0.25.0/README_chinese.md
--- old/httpx-0.24.1/README_chinese.md  2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/README_chinese.md  2023-09-11 12:13:24.000000000 +0200
@@ -101,7 +101,7 @@
 $ pip install httpx[http2]
 ```
 
-HTTPX 要求 Python 3.7+ 版本。
+HTTPX 要求 Python 3.8+ 版本。
 
 ## 文档
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/advanced.md 
new/httpx-0.25.0/docs/advanced.md
--- old/httpx-0.24.1/docs/advanced.md   2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/advanced.md   2023-09-11 12:13:24.000000000 +0200
@@ -426,6 +426,38 @@
 
 ![rich progress bar](img/rich-progress.gif)
 
+## Monitoring upload progress
+
+If you need to monitor upload progress of large responses, you can use request 
content generator streaming.
+
+For example, showing a progress bar using the 
[`tqdm`](https://github.com/tqdm/tqdm) library.
+
+```python
+import io
+import random
+
+import httpx
+from tqdm import tqdm
+
+
+def gen():
+    """
+    this is a complete example with generated random bytes.
+    you can replace `io.BytesIO` with real file object.
+    """
+    total = 32 * 1024 * 1024  # 32m
+    with tqdm(ascii=True, unit_scale=True, unit='B', unit_divisor=1024, 
total=total) as bar:
+        with io.BytesIO(random.randbytes(total)) as f:
+            while data := f.read(1024):
+                yield data
+                bar.update(len(data))
+
+
+httpx.post("https://httpbin.org/post";, content=gen())
+```
+
+![tqdm progress bar](img/tqdm-progress.gif)
+
 ## .netrc Support
 
 HTTPX can be configured to use [a `.netrc` config 
file](https://everything.curl.dev/usingcurl/netrc) for authentication.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/api.md new/httpx-0.25.0/docs/api.md
--- old/httpx-0.24.1/docs/api.md        2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/api.md        2023-09-11 12:13:24.000000000 +0200
@@ -70,7 +70,7 @@
   * The amount of time elapsed between sending the request and calling 
`close()` on the corresponding response received for that request.
   
[total_seconds()](https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds)
 to correctly get
   the total elapsed seconds.
-* `def .raise_for_status()` - **None**
+* `def .raise_for_status()` - **Response**
 * `def .json()` - **Any**
 * `def .read()` - **bytes**
 * `def .iter_raw([chunk_size])` - **bytes iterator**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/async.md 
new/httpx-0.25.0/docs/async.md
--- old/httpx-0.24.1/docs/async.md      2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/async.md      2023-09-11 12:13:24.000000000 +0200
@@ -53,6 +53,9 @@
     ...
 ```
 
+!!! warning
+In order to get the most benefit from connection pooling, make sure you're not 
instantiating multiple client instances - for example by using `async with` 
inside a "hot loop". This can be achieved either by having a single scoped 
client that's passed throughout wherever it's needed, or by having a single 
global client instance.
+
 Alternatively, use `await client.aclose()` if you want to close a client 
explicitly:
 
 ```python
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/index.md 
new/httpx-0.25.0/docs/index.md
--- old/httpx-0.24.1/docs/index.md      2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/index.md      2023-09-11 12:13:24.000000000 +0200
@@ -144,6 +144,6 @@
 $ pip install httpx[brotli]
 ```
 
-HTTPX requires Python 3.7+
+HTTPX requires Python 3.8+
 
 [sync-support]: https://github.com/encode/httpx/issues/572
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/logging.md 
new/httpx-0.25.0/docs/logging.md
--- old/httpx-0.24.1/docs/logging.md    2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/logging.md    2023-09-11 12:13:24.000000000 +0200
@@ -41,7 +41,7 @@
 DEBUG [2023-03-16 14:36:21] httpcore - connection.close.complete
 ```
 
-Logging output includes information from both the high-level `httpx` logger, 
and the network-level `httpcore` logger, which can be configured seperately.
+Logging output includes information from both the high-level `httpx` logger, 
and the network-level `httpcore` logger, which can be configured separately.
 
 For handling more complex logging configurations you might want to use the 
dictionary configuration style...
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/quickstart.md 
new/httpx-0.25.0/docs/quickstart.md
--- old/httpx-0.24.1/docs/quickstart.md 2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/quickstart.md 2023-09-11 12:13:24.000000000 +0200
@@ -285,15 +285,22 @@
   File "/Users/tomchristie/GitHub/encode/httpcore/httpx/models.py", line 837, 
in raise_for_status
     raise HTTPStatusError(message, response=self)
 httpx._exceptions.HTTPStatusError: 404 Client Error: Not Found for url: 
https://httpbin.org/status/404
-For more information check: https://httpstatuses.com/404
+For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
 ```
 
-Any successful response codes will simply return `None` rather than raising an 
exception.
+Any successful response codes will return the `Response` instance rather than 
raising an exception.
 
 ```pycon
 >>> r.raise_for_status()
 ```
 
+The method returns the response instance, allowing you to use it inline. For 
example:
+
+```pycon
+>>> r = httpx.get('...').raise_for_status()
+>>> data = httpx.get('...').raise_for_status().json()
+```
+
 ## Response Headers
 
 The response headers are available as a dictionary-like interface.
@@ -367,7 +374,7 @@
 
 ```pycon
 >>> with httpx.stream("GET", "https://www.example.com";) as r:
-...     if r.headers['Content-Length'] < TOO_LONG:
+...     if int(r.headers['Content-Length']) < TOO_LONG:
 ...         r.read()
 ...         print(r.text)
 ```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/docs/third_party_packages.md 
new/httpx-0.25.0/docs/third_party_packages.md
--- old/httpx-0.24.1/docs/third_party_packages.md       2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/docs/third_party_packages.md       2023-09-11 
12:13:24.000000000 +0200
@@ -6,6 +6,12 @@
 
 <!-- NOTE: this list is in alphabetical order. -->
 
+### Hishel
+
+[GitHub](https://github.com/karosis88/hishel) - 
[Documentation](https://karosis88.github.io/hishel/)
+
+An elegant HTTP Cache implementation for HTTPX and HTTP Core.
+
 ### Authlib
 
 [GitHub](https://github.com/lepture/authlib) - 
[Documentation](https://docs.authlib.org/en/latest/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/__version__.py 
new/httpx-0.25.0/httpx/__version__.py
--- old/httpx-0.24.1/httpx/__version__.py       2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/httpx/__version__.py       2023-09-11 12:13:24.000000000 
+0200
@@ -1,3 +1,3 @@
 __title__ = "httpx"
 __description__ = "A next generation HTTP client, for Python 3."
-__version__ = "0.24.1"
+__version__ = "0.25.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_compat.py 
new/httpx-0.25.0/httpx/_compat.py
--- old/httpx-0.24.1/httpx/_compat.py   2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_compat.py   2023-09-11 12:13:24.000000000 +0200
@@ -17,7 +17,7 @@
         brotli = None
 
 if sys.version_info >= (3, 10) or (
-    sys.version_info >= (3, 7) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7)
+    sys.version_info >= (3, 8) and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0, 7)
 ):
 
     def set_minimum_tls_version_1_2(context: ssl.SSLContext) -> None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_config.py 
new/httpx-0.25.0/httpx/_config.py
--- old/httpx-0.24.1/httpx/_config.py   2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_config.py   2023-09-11 12:13:24.000000000 +0200
@@ -326,6 +326,7 @@
         self,
         url: URLTypes,
         *,
+        ssl_context: typing.Optional[ssl.SSLContext] = None,
         auth: typing.Optional[typing.Tuple[str, str]] = None,
         headers: typing.Optional[HeaderTypes] = None,
     ):
@@ -343,6 +344,7 @@
         self.url = url
         self.auth = auth
         self.headers = headers
+        self.ssl_context = ssl_context
 
     @property
     def raw_auth(self) -> typing.Optional[typing.Tuple[bytes, bytes]]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_models.py 
new/httpx-0.25.0/httpx/_models.py
--- old/httpx-0.24.1/httpx/_models.py   2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_models.py   2023-09-11 12:13:24.000000000 +0200
@@ -467,7 +467,7 @@
         # the client will set `response.next_request`.
         self.next_request: typing.Optional[Request] = None
 
-        self.extensions = {} if extensions is None else extensions
+        self.extensions: ResponseExtensions = {} if extensions is None else 
extensions
         self.history = [] if history is None else list(history)
 
         self.is_closed = False
@@ -711,7 +711,7 @@
             and "Location" in self.headers
         )
 
-    def raise_for_status(self) -> None:
+    def raise_for_status(self) -> "Response":
         """
         Raise the `HTTPStatusError` if one occurred.
         """
@@ -723,18 +723,18 @@
             )
 
         if self.is_success:
-            return
+            return self
 
         if self.has_redirect_location:
             message = (
                 "{error_type} '{0.status_code} {0.reason_phrase}' for url 
'{0.url}'\n"
                 "Redirect location: '{0.headers[location]}'\n"
-                "For more information check: 
https://httpstatuses.com/{0.status_code}";
+                "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}";
             )
         else:
             message = (
                 "{error_type} '{0.status_code} {0.reason_phrase}' for url 
'{0.url}'\n"
-                "For more information check: 
https://httpstatuses.com/{0.status_code}";
+                "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}";
             )
 
         status_class = self.status_code // 100
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_transports/asgi.py 
new/httpx-0.25.0/httpx/_transports/asgi.py
--- old/httpx-0.24.1/httpx/_transports/asgi.py  2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/httpx/_transports/asgi.py  2023-09-11 12:13:24.000000000 
+0200
@@ -161,9 +161,15 @@
         try:
             await self.app(scope, receive, send)
         except Exception:  # noqa: PIE-786
-            if self.raise_app_exceptions or not response_complete.is_set():
+            if self.raise_app_exceptions:
                 raise
 
+            response_complete.set()
+            if status_code is None:
+                status_code = 500
+            if response_headers is None:
+                response_headers = {}
+
         assert response_complete.is_set()
         assert status_code is not None
         assert response_headers is not None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_transports/default.py 
new/httpx-0.25.0/httpx/_transports/default.py
--- old/httpx-0.24.1/httpx/_transports/default.py       2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_transports/default.py       2023-09-11 
12:13:24.000000000 +0200
@@ -53,6 +53,12 @@
 T = typing.TypeVar("T", bound="HTTPTransport")
 A = typing.TypeVar("A", bound="AsyncHTTPTransport")
 
+SOCKET_OPTION = typing.Union[
+    typing.Tuple[int, int, int],
+    typing.Tuple[int, int, typing.Union[bytes, bytearray]],
+    typing.Tuple[int, int, None, int],
+]
+
 
 @contextlib.contextmanager
 def map_httpcore_exceptions() -> typing.Iterator[None]:
@@ -122,6 +128,7 @@
         uds: typing.Optional[str] = None,
         local_address: typing.Optional[str] = None,
         retries: int = 0,
+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
     ) -> None:
         ssl_context = create_ssl_context(verify=verify, cert=cert, 
trust_env=trust_env)
 
@@ -136,6 +143,7 @@
                 uds=uds,
                 local_address=local_address,
                 retries=retries,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme in ("http", "https"):
             self._pool = httpcore.HTTPProxy(
@@ -148,11 +156,13 @@
                 proxy_auth=proxy.raw_auth,
                 proxy_headers=proxy.headers.raw,
                 ssl_context=ssl_context,
+                proxy_ssl_context=proxy.ssl_context,
                 max_connections=limits.max_connections,
                 max_keepalive_connections=limits.max_keepalive_connections,
                 keepalive_expiry=limits.keepalive_expiry,
                 http1=http1,
                 http2=http2,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme == "socks5":
             try:
@@ -257,6 +267,7 @@
         uds: typing.Optional[str] = None,
         local_address: typing.Optional[str] = None,
         retries: int = 0,
+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
     ) -> None:
         ssl_context = create_ssl_context(verify=verify, cert=cert, 
trust_env=trust_env)
 
@@ -271,6 +282,7 @@
                 uds=uds,
                 local_address=local_address,
                 retries=retries,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme in ("http", "https"):
             self._pool = httpcore.AsyncHTTPProxy(
@@ -288,6 +300,7 @@
                 keepalive_expiry=limits.keepalive_expiry,
                 http1=http1,
                 http2=http2,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme == "socks5":
             try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_transports/wsgi.py 
new/httpx-0.25.0/httpx/_transports/wsgi.py
--- old/httpx-0.24.1/httpx/_transports/wsgi.py  2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/httpx/_transports/wsgi.py  2023-09-11 12:13:24.000000000 
+0200
@@ -102,6 +102,7 @@
             "QUERY_STRING": request.url.query.decode("ascii"),
             "SERVER_NAME": request.url.host,
             "SERVER_PORT": str(port),
+            "SERVER_PROTOCOL": "HTTP/1.1",
             "REMOTE_ADDR": self.remote_addr,
         }
         for header_key, header_value in request.headers.raw:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_types.py 
new/httpx-0.25.0/httpx/_types.py
--- old/httpx-0.24.1/httpx/_types.py    2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_types.py    2023-09-11 12:13:24.000000000 +0200
@@ -16,6 +16,7 @@
     Iterator,
     List,
     Mapping,
+    MutableMapping,
     NamedTuple,
     Optional,
     Sequence,
@@ -87,7 +88,7 @@
 
 RequestContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]]
 ResponseContent = Union[str, bytes, Iterable[bytes], AsyncIterable[bytes]]
-ResponseExtensions = Mapping[str, Any]
+ResponseExtensions = MutableMapping[str, Any]
 
 RequestData = Mapping[str, Any]
 
@@ -104,7 +105,7 @@
 ]
 RequestFiles = Union[Mapping[str, FileTypes], Sequence[Tuple[str, FileTypes]]]
 
-RequestExtensions = Mapping[str, Any]
+RequestExtensions = MutableMapping[str, Any]
 
 
 class SyncByteStream:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_urlparse.py 
new/httpx-0.25.0/httpx/_urlparse.py
--- old/httpx-0.24.1/httpx/_urlparse.py 2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_urlparse.py 2023-09-11 12:13:24.000000000 +0200
@@ -260,8 +260,10 @@
     # For 'path' we need to drop ? and # from the GEN_DELIMS set.
     parsed_path: str = quote(path, safe=SUB_DELIMS + ":/[]@")
     # For 'query' we need to drop '#' from the GEN_DELIMS set.
+    # We also exclude '/' because it is more robust to replace it with a 
percent
+    # encoding despite it not being a requirement of the spec.
     parsed_query: typing.Optional[str] = (
-        None if query is None else quote(query, safe=SUB_DELIMS + ":/?[]@")
+        None if query is None else quote(query, safe=SUB_DELIMS + ":?[]@")
     )
     # For 'fragment' we can include all of the GEN_DELIMS set.
     parsed_fragment: typing.Optional[str] = (
@@ -452,11 +454,11 @@
     #
     # 
https://github.com/python/cpython/blob/b2f7b2ef0b5421e01efb8c7bee2ef95d3bab77eb/Lib/urllib/parse.py#L926
     #
-    # Note that we use '%20' encoding for spaces, and treat '/' as a safe
-    # character. This means our query params have the same escaping as other
-    # characters in the URL path. This is slightly different to `requests`,
-    # but is the behaviour that browsers use.
+    # Note that we use '%20' encoding for spaces. and '%2F  for '/'.
+    # This is slightly different than `requests`, but is the behaviour that 
browsers use.
     #
-    # See https://github.com/encode/httpx/issues/2536 and
-    # 
https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
-    return "&".join([quote(k) + "=" + quote(v) for k, v in items])
+    # See
+    # - https://github.com/encode/httpx/issues/2536
+    # - https://github.com/encode/httpx/issues/2721
+    # - 
https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
+    return "&".join([quote(k, safe="") + "=" + quote(v, safe="") for k, v in 
items])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/httpx/_utils.py 
new/httpx-0.25.0/httpx/_utils.py
--- old/httpx-0.24.1/httpx/_utils.py    2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/httpx/_utils.py    2023-09-11 12:13:24.000000000 +0200
@@ -357,12 +357,12 @@
     A utility class currently used for making lookups against proxy keys...
 
     # Wildcard matching...
-    >>> pattern = URLPattern("all")
+    >>> pattern = URLPattern("all://")
     >>> pattern.matches(httpx.URL("http://example.com";))
     True
 
     # Witch scheme matching...
-    >>> pattern = URLPattern("https")
+    >>> pattern = URLPattern("https://";)
     >>> pattern.matches(httpx.URL("https://example.com";))
     True
     >>> pattern.matches(httpx.URL("http://example.com";))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/pyproject.toml 
new/httpx-0.25.0/pyproject.toml
--- old/httpx-0.24.1/pyproject.toml     2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/pyproject.toml     2023-09-11 12:13:24.000000000 +0200
@@ -6,7 +6,7 @@
 name = "httpx"
 description = "The next generation HTTP client."
 license = "BSD-3-Clause"
-requires-python = ">=3.7"
+requires-python = ">=3.8"
 authors = [
     { name = "Tom Christie", email = "t...@tomchristie.com" },
 ]
@@ -20,7 +20,6 @@
     "Operating System :: OS Independent",
     "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",
@@ -29,7 +28,7 @@
 ]
 dependencies = [
     "certifi",
-    "httpcore>=0.15.0,<0.18.0",
+    "httpcore>=0.18.0,<0.19.0",
     "idna",
     "sniffio",
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/requirements.txt 
new/httpx-0.25.0/requirements.txt
--- old/httpx-0.24.1/requirements.txt   2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/requirements.txt   2023-09-11 12:13:24.000000000 +0200
@@ -6,27 +6,27 @@
 
 # Optional charset auto-detection
 # Used in our test cases
-chardet==5.1.0
+chardet==5.2.0
 types-chardet==5.0.4.5
 
 # Documentation
-mkdocs==1.4.2
+mkdocs==1.5.2
 mkautodoc==0.2.0
-mkdocs-material==9.1.5
+mkdocs-material==9.2.6
 
 # Packaging
 build==0.10.0
 twine==4.0.2
 
 # Tests & Linting
-black==23.3.0
-coverage[toml]==7.2.2
-cryptography==40.0.2
-mypy==1.0.1
+black==23.7.0
+coverage[toml]==7.3.0
+cryptography==41.0.3
+mypy==1.5.1
 types-certifi==2021.10.8.2
-pytest==7.2.2
-ruff==0.0.260
-trio==0.22.0
+pytest==7.4.0
+ruff==0.0.286
+trio==0.22.2
 trio-typing==0.8.0
-trustme==1.0.0
+trustme==1.1.0
 uvicorn==0.22.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/scripts/check 
new/httpx-0.25.0/scripts/check
--- old/httpx-0.24.1/scripts/check      2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/scripts/check      2023-09-11 12:13:24.000000000 +0200
@@ -9,6 +9,6 @@
 set -x
 
 ./scripts/sync-version
-${PREFIX}black --check --diff --target-version=py37 $SOURCE_FILES
+${PREFIX}black --check --diff $SOURCE_FILES
 ${PREFIX}mypy $SOURCE_FILES
 ${PREFIX}ruff check $SOURCE_FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/scripts/lint 
new/httpx-0.25.0/scripts/lint
--- old/httpx-0.24.1/scripts/lint       2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/scripts/lint       2023-09-11 12:13:24.000000000 +0200
@@ -1,7 +1,7 @@
 #!/bin/sh -e
 
 export PREFIX=""
-if [ -d 'venv' ] ; then
+if [ -d 'venv' ]; then
     export PREFIX="venv/bin/"
 fi
 export SOURCE_FILES="httpx tests"
@@ -9,4 +9,4 @@
 set -x
 
 ${PREFIX}ruff --fix $SOURCE_FILES
-${PREFIX}black --target-version=py37 $SOURCE_FILES
+${PREFIX}black $SOURCE_FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/client/test_async_client.py 
new/httpx-0.25.0/tests/client/test_async_client.py
--- old/httpx-0.24.1/tests/client/test_async_client.py  2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/tests/client/test_async_client.py  2023-09-11 
12:13:24.000000000 +0200
@@ -122,7 +122,7 @@
                     response.raise_for_status()
                 assert exc_info.value.response == response
             else:
-                assert response.raise_for_status() is None  # type: ignore
+                assert response.raise_for_status() is response
 
 
 @pytest.mark.anyio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/client/test_client.py 
new/httpx-0.25.0/tests/client/test_client.py
--- old/httpx-0.24.1/tests/client/test_client.py        2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/tests/client/test_client.py        2023-09-11 
12:13:24.000000000 +0200
@@ -141,7 +141,7 @@
                 assert exc_info.value.response == response
                 assert exc_info.value.request.url.path == 
f"/status/{status_code}"
             else:
-                assert response.raise_for_status() is None  # type: ignore
+                assert response.raise_for_status() is response
 
 
 def test_options(server):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/models/test_responses.py 
new/httpx-0.25.0/tests/models/test_responses.py
--- old/httpx-0.24.1/tests/models/test_responses.py     2023-05-18 
13:03:21.000000000 +0200
+++ new/httpx-0.25.0/tests/models/test_responses.py     2023-09-11 
12:13:24.000000000 +0200
@@ -102,7 +102,7 @@
         response.raise_for_status()
     assert str(exc_info.value) == (
         "Informational response '101 Switching Protocols' for url 
'https://example.org'\n"
-        "For more information check: https://httpstatuses.com/101";
+        "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101";
     )
 
     # 3xx status codes are redirections.
@@ -114,7 +114,7 @@
     assert str(exc_info.value) == (
         "Redirect response '303 See Other' for url 'https://example.org'\n"
         "Redirect location: 'https://other.org'\n"
-        "For more information check: https://httpstatuses.com/303";
+        "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303";
     )
 
     # 4xx status codes are a client error.
@@ -125,7 +125,7 @@
         response.raise_for_status()
     assert str(exc_info.value) == (
         "Client error '403 Forbidden' for url 'https://example.org'\n"
-        "For more information check: https://httpstatuses.com/403";
+        "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403";
     )
 
     # 5xx status codes are a server error.
@@ -136,7 +136,7 @@
         response.raise_for_status()
     assert str(exc_info.value) == (
         "Server error '500 Internal Server Error' for url 
'https://example.org'\n"
-        "For more information check: https://httpstatuses.com/500";
+        "For more information check: 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500";
     )
 
     # Calling .raise_for_status without setting a request instance is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/models/test_url.py 
new/httpx-0.25.0/tests/models/test_url.py
--- old/httpx-0.24.1/tests/models/test_url.py   2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/tests/models/test_url.py   2023-09-11 12:13:24.000000000 
+0200
@@ -360,10 +360,10 @@
     and https://github.com/encode/httpx/discussions/2460
     """
     url = httpx.URL("https://www.example.com/?a=b c&d=e/f")
-    assert url.raw_path == b"/?a=b%20c&d=e/f"
+    assert url.raw_path == b"/?a=b%20c&d=e%2Ff"
 
     url = httpx.URL("https://www.example.com/";, params={"a": "b c", "d": 
"e/f"})
-    assert url.raw_path == b"/?a=b%20c&d=e/f"
+    assert url.raw_path == b"/?a=b%20c&d=e%2Ff"
 
 
 def test_url_with_url_encoded_path():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/test_asgi.py 
new/httpx-0.25.0/tests/test_asgi.py
--- old/httpx-0.24.1/tests/test_asgi.py 2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/tests/test_asgi.py 2023-09-11 12:13:24.000000000 +0200
@@ -3,6 +3,7 @@
 import pytest
 
 import httpx
+from httpx import ASGITransport
 
 
 async def hello_world(scope, receive, send):
@@ -191,3 +192,12 @@
 
     assert response.status_code == 200
     assert disconnect
+
+
+@pytest.mark.anyio
+async def test_asgi_exc_no_raise():
+    transport = ASGITransport(app=raise_exc, raise_app_exceptions=False)
+    async with httpx.AsyncClient(transport=transport) as client:
+        response = await client.get("http://www.example.org/";)
+
+        assert response.status_code == 500
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/test_config.py 
new/httpx-0.25.0/tests/test_config.py
--- old/httpx-0.24.1/tests/test_config.py       2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/tests/test_config.py       2023-09-11 12:13:24.000000000 
+0200
@@ -1,6 +1,5 @@
 import os
 import ssl
-import sys
 from pathlib import Path
 
 import certifi
@@ -176,28 +175,26 @@
     not hasattr(ssl.SSLContext, "keylog_filename"),
     reason="requires OpenSSL 1.1.1 or higher",
 )
-@pytest.mark.skipif(sys.version_info < (3, 8), reason="requires python3.8 or 
higher")
 def test_ssl_config_support_for_keylog_file(tmpdir, monkeypatch):  # pragma: 
no cover
-    if sys.version_info > (3, 8):
-        with monkeypatch.context() as m:
-            m.delenv("SSLKEYLOGFILE", raising=False)
+    with monkeypatch.context() as m:
+        m.delenv("SSLKEYLOGFILE", raising=False)
 
-            context = httpx.create_ssl_context(trust_env=True)
+        context = httpx.create_ssl_context(trust_env=True)
 
-            assert context.keylog_filename is None
+        assert context.keylog_filename is None
 
-        filename = str(tmpdir.join("test.log"))
+    filename = str(tmpdir.join("test.log"))
 
-        with monkeypatch.context() as m:
-            m.setenv("SSLKEYLOGFILE", filename)
+    with monkeypatch.context() as m:
+        m.setenv("SSLKEYLOGFILE", filename)
 
-            context = httpx.create_ssl_context(trust_env=True)
+        context = httpx.create_ssl_context(trust_env=True)
 
-            assert context.keylog_filename == filename
+        assert context.keylog_filename == filename
 
-            context = httpx.create_ssl_context(trust_env=False)
+        context = httpx.create_ssl_context(trust_env=False)
 
-            assert context.keylog_filename is None
+        assert context.keylog_filename is None
 
 
 def test_proxy_from_url():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/test_urlparse.py 
new/httpx-0.25.0/tests/test_urlparse.py
--- old/httpx-0.24.1/tests/test_urlparse.py     2023-05-18 13:03:21.000000000 
+0200
+++ new/httpx-0.25.0/tests/test_urlparse.py     2023-09-11 12:13:24.000000000 
+0200
@@ -141,7 +141,7 @@
 
 def test_param_with_existing_escape_requires_encoding():
     url = httpx.URL("http://webservice";, params={"u": 
"http://example.com?q=foo%2Fa"})
-    assert str(url) == 
"http://webservice?u=http%3A//example.com%3Fq%3Dfoo%252Fa";
+    assert str(url) == 
"http://webservice?u=http%3A%2F%2Fexample.com%3Fq%3Dfoo%252Fa";
 
 
 # Tests for invalid URLs
@@ -264,9 +264,9 @@
 def test_query_percent_encoding():
     # Test percent encoding for SUB_DELIMS ALPHA NUM and allowable GEN_DELIMS
     url = httpx.URL("https://example.com/?!$&;'()*+,;= abc ABC 123 :/[]@" + "?")
-    assert url.raw_path == b"/?!$&'()*+,;=%20abc%20ABC%20123%20:/[]@?"
+    assert url.raw_path == b"/?!$&'()*+,;=%20abc%20ABC%20123%20:%2F[]@?"
     assert url.path == "/"
-    assert url.query == b"!$&'()*+,;=%20abc%20ABC%20123%20:/[]@?"
+    assert url.query == b"!$&'()*+,;=%20abc%20ABC%20123%20:%2F[]@?"
     assert url.fragment == ""
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/httpx-0.24.1/tests/test_wsgi.py 
new/httpx-0.25.0/tests/test_wsgi.py
--- old/httpx-0.24.1/tests/test_wsgi.py 2023-05-18 13:03:21.000000000 +0200
+++ new/httpx-0.25.0/tests/test_wsgi.py 2023-09-11 12:13:24.000000000 +0200
@@ -173,3 +173,20 @@
     assert response.status_code == 200
     assert response.text == "Hello, World!"
     assert server_port == expected_server_port
+
+
+def test_wsgi_server_protocol():
+    server_protocol = None
+
+    def app(environ, start_response):
+        nonlocal server_protocol
+        server_protocol = environ["SERVER_PROTOCOL"]
+        start_response("200 OK", [("Content-Type", "text/plain")])
+        return [b"success"]
+
+    with httpx.Client(app=app, base_url="http://testserver";) as client:
+        response = client.get("/")
+
+    assert response.status_code == 200
+    assert response.text == "success"
+    assert server_protocol == "HTTP/1.1"

Reply via email to