Repository: encode/httpx

Issue:
Support `.trust_env` attribute on the client instance.
We should add a `trust_env` attribute and `__init__` keyword argument to `BaseClient`.
This should be used as the default if `trust_env` is not explicitly specified on the request.

The default value for `trust_env` on the per-method calls should then switch to `None`, so that we can distinguish it from "explicitly True" and "explicitly False".

This'd be a nice enhancement on top of #177.


Discussion:

Resolving patch:
diff --git a/httpx/api.py b/httpx/api.py
--- a/httpx/api.py
+++ b/httpx/api.py
@@ -32,7 +32,7 @@ def request(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     stream: bool = False,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     with Client() as client:
         return client.request(
@@ -66,7 +66,7 @@ def get(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "GET",
@@ -96,7 +96,7 @@ def options(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "OPTIONS",
@@ -126,7 +126,7 @@ def head(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "HEAD",
@@ -159,7 +159,7 @@ def post(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "POST",
@@ -195,7 +195,7 @@ def put(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "PUT",
@@ -231,7 +231,7 @@ def patch(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "PATCH",
@@ -267,7 +267,7 @@ def delete(
     cert: CertTypes = None,
     verify: VerifyTypes = True,
     timeout: TimeoutTypes = None,
-    trust_env: bool = True,
+    trust_env: bool = None,
 ) -> Response:
     return request(
         "DELETE",
diff --git a/httpx/client.py b/httpx/client.py
--- a/httpx/client.py
+++ b/httpx/client.py
@@ -65,7 +65,7 @@ def __init__(
         app: typing.Callable = None,
         raise_app_exceptions: bool = True,
         backend: ConcurrencyBackend = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ):
         if backend is None:
             backend = AsyncioBackend()
@@ -106,7 +106,7 @@ def __init__(
         self.max_redirects = max_redirects
         self.dispatch = async_dispatch
         self.concurrency_backend = backend
-        self.trust_env = trust_env
+        self.trust_env = True if trust_env is None else trust_env
 
     def merge_url(self, url: URLTypes) -> URL:
         url = self.base_url.join(relative_url=url)
@@ -142,7 +142,7 @@ async def send(
         verify: VerifyTypes = None,
         cert: CertTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         if auth is None:
             auth = self.auth
@@ -155,7 +155,7 @@ async def send(
         if auth is None:
             if url.username or url.password:
                 auth = HTTPBasicAuth(username=url.username, password=url.password)
-            elif trust_env:
+            elif self.trust_env if trust_env is None else trust_env:
                 netrc_login = get_netrc_login(url.authority)
                 if netrc_login:
                     netrc_username, _, netrc_password = netrc_login
@@ -342,7 +342,7 @@ async def get(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "GET",
@@ -372,7 +372,7 @@ async def options(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "OPTIONS",
@@ -402,7 +402,7 @@ async def head(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "HEAD",
@@ -435,7 +435,7 @@ async def post(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "POST",
@@ -471,7 +471,7 @@ async def put(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "PUT",
@@ -507,7 +507,7 @@ async def patch(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "PATCH",
@@ -543,7 +543,7 @@ async def delete(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         return await self.request(
             "DELETE",
@@ -580,7 +580,7 @@ async def request(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> AsyncResponse:
         url = self.merge_url(url)
         headers = self.merge_headers(headers)
@@ -664,7 +664,7 @@ def request(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         url = self.merge_url(url)
         headers = self.merge_headers(headers)
@@ -733,7 +733,7 @@ def get(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "GET",
@@ -763,7 +763,7 @@ def options(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "OPTIONS",
@@ -793,7 +793,7 @@ def head(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "HEAD",
@@ -826,7 +826,7 @@ def post(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "POST",
@@ -862,7 +862,7 @@ def put(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "PUT",
@@ -898,7 +898,7 @@ def patch(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "PATCH",
@@ -934,7 +934,7 @@ def delete(
         cert: CertTypes = None,
         verify: VerifyTypes = None,
         timeout: TimeoutTypes = None,
-        trust_env: bool = True,
+        trust_env: bool = None,
     ) -> Response:
         return self.request(
             "DELETE",


Test patch:
diff --git a/tests/client/test_auth.py b/tests/client/test_auth.py
--- a/tests/client/test_auth.py
+++ b/tests/client/test_auth.py
@@ -92,3 +92,11 @@ def test_trust_env_auth():
 
     assert response.status_code == 200
     assert response.json() == {"auth": None}
+
+    with Client(dispatch=MockDispatch(), trust_env=False) as client:
+        response = client.get(url, trust_env=True)
+
+    assert response.status_code == 200
+    assert response.json() == {
+        "auth": "Basic ZXhhbXBsZS11c2VybmFtZTpleGFtcGxlLXBhc3N3b3Jk"
+    }