Repository: encode/httpx

Issue:
Breaking drop of URL.raw in patch release 0.23.1
The patch release `0.23.1` included a breaking change in #2241 

The justification seems to be that "we don't use it", but `url.raw` is a public property used by other libraries including `ddtrace` 0.x versions: https://github.com/DataDog/dd-trace-py/blob/v0.61.3/ddtrace/contrib/httpx/patch.py#L41 

Can this breaking change be reverted and maybe soft-deprecated? @tomchristie @michaeloliverx 

Discussion:
tomchristie: Okay, let's go with this.

We'll want a new minor point release.

Patch:
diff --git a/httpx/_types.py b/httpx/_types.py
index f3c1f6e..6b610e1 100644
--- a/httpx/_types.py
+++ b/httpx/_types.py
@@ -16,6 +16,7 @@ from typing import (
     Iterator,
     List,
     Mapping,
+    NamedTuple,
     Optional,
     Sequence,
     Tuple,
@@ -31,6 +32,16 @@ if TYPE_CHECKING:  # pragma: no cover
 
 PrimitiveData = Optional[Union[str, int, float, bool]]
 
+RawURL = NamedTuple(
+    "RawURL",
+    [
+        ("raw_scheme", bytes),
+        ("raw_host", bytes),
+        ("port", Optional[int]),
+        ("raw_path", bytes),
+    ],
+)
+
 URLTypes = Union["URL", str]
 
 QueryParamTypes = Union[
diff --git a/httpx/_urls.py b/httpx/_urls.py
index ab39c2e..f26b2eb 100644
--- a/httpx/_urls.py
+++ b/httpx/_urls.py
@@ -6,7 +6,7 @@ import rfc3986
 import rfc3986.exceptions
 
 from ._exceptions import InvalidURL
-from ._types import PrimitiveData, QueryParamTypes, URLTypes
+from ._types import PrimitiveData, QueryParamTypes, RawURL, URLTypes
 from ._utils import primitive_value_to_str
 
 
@@ -311,6 +311,21 @@ class URL:
         """
         return unquote(self._uri_reference.fragment or "")
 
+    @property
+    def raw(self) -> RawURL:
+        """
+        Provides the (scheme, host, port, target) for the outgoing request.
+
+        In older versions of `httpx` this was used in the low-level transport API.
+        We no longer use `RawURL`, and this property will be deprecated in a future release.
+        """
+        return RawURL(
+            self.raw_scheme,
+            self.raw_host,
+            self.port,
+            self.raw_path,
+        )
+
     @property
     def is_absolute_url(self) -> bool:
         """


Test patch:
diff --git a/tests/models/test_url.py b/tests/models/test_url.py
index 321cffb..959681b 100644
--- a/tests/models/test_url.py
+++ b/tests/models/test_url.py
@@ -424,3 +424,13 @@ def test_ipv6_url_from_raw_url(host):
     assert url.host == "::ffff:192.168.0.1"
     assert url.netloc == b"[::ffff:192.168.0.1]"
     assert str(url) == "https://[::ffff:192.168.0.1]/"
+
+
+def test_url_raw_compatibility():
+    url = httpx.URL("https://www.example.com/path")
+    scheme, host, port, raw_path = url.raw
+
+    assert scheme == b"https"
+    assert host == b"www.example.com"
+    assert port is None
+    assert raw_path == b"/path"