Repository: encode/httpx

Issue:
`Response.url` is somewhere listed as optional and elsewhere not
### Discussed in https://github.com/encode/httpx/discussions/1908

<div type='discussions-op-text'>

<sup>Originally posted by **septatrix** October 22, 2021</sup>
In the method signature it is declared as optional however in the docs it is stated as being non-optional.
The latter seems to make more sense as the value is directly linked to the url of the request which should not be none.
This currently leeds to some false positives with mypy in our codebase.

https://github.com/encode/httpx/blob/62b1666dc6c6b012b258574c4239b8ff8f481619/httpx/_models.py#L1304-L1309

https://github.com/encode/httpx/blob/62b1666dc6c6b012b258574c4239b8ff8f481619/docs/api.md#L59</div>


Discussion:
Okay, so...

As it stands the docs are incorrect. The type annotation is `Optional[URL]`.
However we've got two possible options here. In order to understand why we've got two options, let me talk through why it's optional.

Whenever you're making a request via `httpx` you'll always end up with the corresponding response having an associated `.url`. Makes sense, since it is always associated with an incoming request.

However, the `httpx` API does also let you instantiate a `Response()` instance directly. In this case, the instance *might* not be associated with an incoming request. As a result `.url` is currently optional.

Our two options here...

1. Update the documentation to reflect that `.url` is optional.
2. Make `.url` *not* be optional, but if it is accessed on a bare response instance, with no associated request, then have it raise something like `RuntimeError("Attempted to access '.url', on a response which has no associated request")`.

I *quite* like the idea of 2, because it would mean that the type annotation for `.url` can be non-optional, and for the vast proportion of use cases that'll be what our users would want.
I would also lean towards the second option as that makes it a lot cleaner to write code without mypy marking something as wrong. Actually that is also (almost) what currently happens:

```python
>>> httpx.Response(200).url
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/septatrix/Documents/programming/syncMyMoodle/.venv/lib64/python3.9/site-packages/httpx/_models.py", line 1308, in url
    return self.request.url
  File "/home/septatrix/Documents/programming/syncMyMoodle/.venv/lib64/python3.9/site-packages/httpx/_models.py", line 1280, in request
    raise RuntimeError(
RuntimeError: The request instance has not been set on this response.
```
> Actually that is also (almost) what currently happens:

Oh right, yes. In that case actually all we need to do is change the type annotation so that it's not marked as `Optional`.
We've already got (close enough to) the behaviour we want.

Resolving patch:
diff --git a/httpx/_models.py b/httpx/_models.py
--- a/httpx/_models.py
+++ b/httpx/_models.py
@@ -1302,7 +1302,7 @@ def reason_phrase(self) -> str:
             return codes.get_reason_phrase(self.status_code)
 
     @property
-    def url(self) -> typing.Optional[URL]:
+    def url(self) -> URL:
         """
         Returns the URL for which the request was made.
         """


Test patch: