tomchristie: > I suppose this moves us forward relative to minimal dependencies, eg we’ll now be able to not require h2 unless users want to use HTTP/2?

Ah yeah I'd forgotten about that. We *can also* make that switch here, yup.
I guess we would drop `h2` out of our default install, and into `extra_requires`, so...

`pip install httpx[h2]`

And a check on the client for "if http_2 is True and h2 is not installed then error".
florimondmanca: > We can also make that switch here, yup.

I’d rather we deal with it later, this PR is quite a big chunk already. :-)
tomchristie: Good call.
tomchristie: Should we use `httpx.Client(http_2=True)` or `httpx.Client(http2=True)`?

I think the later is probably neater, right?
diff --git a/docs/advanced.md b/docs/advanced.md
index d087bd2..9b1502f 100644
--- a/docs/advanced.md
+++ b/docs/advanced.md
@@ -141,20 +141,6 @@ make modifications before sending the request.
 <Response [200 OK]>
 ```
 
-## Specify the version of the HTTP protocol
-
-One can set the version of the HTTP protocol for the client in case you want to make the requests using a specific version.
-
-For example:
-
-```python
-async with httpx.Client(http_versions=["HTTP/1.1"]) as h11_client:
-    h11_response = await h11_client.get("https://myserver.com")
-
-async with httpx.Client(http_versions=["HTTP/2"]) as h2_client:
-    h2_response = await h2_client.get("https://myserver.com")
-```
-
 ## .netrc Support
 
 HTTPX supports .netrc file. In `trust_env=True` cases, if auth parameter is
@@ -367,7 +353,7 @@ More specifically, if a tuple is used as a value, it must have between 2 and 3 e
 - The first element is an optional file name which can be set to `None`.
 - The second element may be a file-like object or a string which will be automatically
 encoded in UTF-8.
-- An optional third element can be used to specify the 
+- An optional third element can be used to specify the
 [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_Types)
 of the file being uploaded. If not specified HTTPX will attempt to guess the MIME type based
 on the file name, with unknown file extensions defaulting to "application/octet-stream".
diff --git a/docs/http2.md b/docs/http2.md
new file mode 100644
index 0000000..66d835d
--- /dev/null
+++ b/docs/http2.md
@@ -0,0 +1,60 @@
+# HTTP/2
+
+HTTP/2 is a major new iteration of the HTTP protocol, that provides a far more
+efficient transport, with potential performance benefits. HTTP/2 does not change
+the core semantics of the request or response, but alters the way that data is
+sent to and from the server.
+
+Rather that the text format that HTTP/1.1 uses, HTTP/2 is a binary format.
+The binary format provides full request and response multiplexing, and efficient
+compression of HTTP headers. The stream multiplexing means that where HTTP/1.1
+requires one TCP stream for each concurrent request, HTTP/2 allows a single TCP
+stream to handle multiple concurrent requests.
+
+HTTP/2 also provides support for functionality such as response prioritization,
+and server push.
+
+For a comprehensive guide to HTTP/2 you may want to check out "[HTTP2 Explained](https://http2-explained.haxx.se/content/en/)".
+
+## Enabling HTTP/2
+
+The HTTPX client provides provisional HTTP/2 support.
+
+HTTP/2 support is not enabled by default, because HTTP/1.1 is a mature,
+battle-hardened transport layer. With HTTP/2 being newer and significantly more
+complex, our implementation should be considered a less robust option at this
+point in time.
+
+However, if you're issuing highly concurrent requests you might want to consider
+trying out our HTTP/2 support. You can do so by instantiating a client with
+HTTP/2 support enabled:
+
+```python
+client = httpx.Client(http_2=True)
+...
+```
+
+You can also instantiate a client as a context manager, to ensure that all
+HTTP connections are nicely scoped, and will be closed once the context block
+is exited.
+
+```python
+async with httpx.Client(http_2=True) as client:
+    ...
+```
+
+## Inspecting the HTTP version
+
+Enabling HTTP/2 support on the client does not *necessarily* mean that your
+requests and responses will be transported over HTTP/2, since both the client
+*and* the server need to support HTTP/2. If you connect to a server that only
+supports HTTP/1.1 the client will use a standard HTTP/1.1 connection instead.
+
+You can determine which version of the HTTP protocol was used by examining
+the `.http_version` property on the response.
+
+```python
+client = httpx.Client(http_2=True)
+response = await client.get(...)
+print(response.http_version)  # "HTTP/1.0", "HTTP/1.1", or "HTTP/2".
+```
diff --git a/docs/index.md b/docs/index.md
index 846d58a..c233494 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -64,7 +64,7 @@ HTTPX is a high performance asynchronous HTTP client, that builds on the
 well-established usability of `requests`, and gives you:
 
 * A broadly requests-compatible API.
-* HTTP/2 and HTTP/1.1 support.
+* HTTP/1.1 and [HTTP/2 support](http2.md).
 * Ability to [make requests directly to ASGI applications](advanced.md#calling-into-python-web-apps).
 * Strict timeouts everywhere.
 * Fully type annotated.
@@ -92,7 +92,8 @@ Plus all the standard features of `requests`...
 
 For a run-through of all the basics, head over to the [QuickStart](quickstart.md).
 
-For more advanced topics, see the [Advanced Usage](advanced.md) section.
+For more advanced topics, see the [Advanced Usage](advanced.md) section,
+or the [HTTP/2](http2.md) section.
 
 The [Developer Interface](api.md) provides a comprehensive API reference.
 
diff --git a/httpx/__init__.py b/httpx/__init__.py
index bda76ae..0910545 100644
--- a/httpx/__init__.py
+++ b/httpx/__init__.py
@@ -12,8 +12,6 @@ from .concurrency.base import (
 from .config import (
     USER_AGENT,
     CertTypes,
-    HTTPVersionConfig,
-    HTTPVersionTypes,
     PoolLimits,
     SSLConfig,
     TimeoutConfig,
@@ -118,8 +116,6 @@ __all__ = [
     "StatusCode",
     "codes",
     "TimeoutTypes",
-    "HTTPVersionTypes",
-    "HTTPVersionConfig",
     "AuthTypes",
     "Cookies",
     "CookieTypes",
diff --git a/httpx/api.py b/httpx/api.py
index 2ea1be6..893c3e7 100644
--- a/httpx/api.py
+++ b/httpx/api.py
@@ -81,11 +81,7 @@ async def request(
     ```
     """
     async with Client(
-        http_versions=["HTTP/1.1"],
-        cert=cert,
-        verify=verify,
-        timeout=timeout,
-        trust_env=trust_env,
+        cert=cert, verify=verify, timeout=timeout, trust_env=trust_env,
     ) as client:
         return await client.request(
             method=method,
diff --git a/httpx/client.py b/httpx/client.py
index 1fe4f6c..28aa176 100644
--- a/httpx/client.py
+++ b/httpx/client.py
@@ -12,7 +12,6 @@ from .config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     TimeoutTypes,
     VerifyTypes,
@@ -79,8 +78,8 @@ class Client:
     to authenticate the client. Either a path to an SSL certificate file, or
     two-tuple of (certificate file, key file), or a three-tuple of (certificate
     file, key file, password).
-    * **http_versions** - *(optional)* A list of strings of HTTP protocol
-    versions to use when sending requests. eg. `http_versions=["HTTP/1.1"]`
+    * **http_2** - *(optional)* A boolean indicating if HTTP/2 support should be
+    enabled. Defaults to `False`.
     * **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy
     URLs.
     * **timeout** - *(optional)* The timeout configuration to use when sending
@@ -111,7 +110,7 @@ class Client:
         cookies: CookieTypes = None,
         verify: VerifyTypes = True,
         cert: CertTypes = None,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         proxies: ProxiesTypes = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
@@ -134,7 +133,7 @@ class Client:
                 verify=verify,
                 cert=cert,
                 timeout=timeout,
-                http_versions=http_versions,
+                http_2=http_2,
                 pool_limits=pool_limits,
                 backend=backend,
                 trust_env=trust_env,
@@ -167,7 +166,7 @@ class Client:
             verify=verify,
             cert=cert,
             timeout=timeout,
-            http_versions=http_versions,
+            http_2=http_2,
             pool_limits=pool_limits,
             backend=backend,
             trust_env=trust_env,
@@ -833,13 +832,13 @@ def _proxies_to_dispatchers(
     verify: VerifyTypes,
     cert: typing.Optional[CertTypes],
     timeout: TimeoutTypes,
-    http_versions: typing.Optional[HTTPVersionTypes],
+    http_2: bool,
     pool_limits: PoolLimits,
     backend: ConcurrencyBackend,
     trust_env: bool,
 ) -> typing.Dict[str, Dispatcher]:
     def _proxy_from_url(url: URLTypes) -> Dispatcher:
-        nonlocal verify, cert, timeout, http_versions, pool_limits, backend, trust_env
+        nonlocal verify, cert, timeout, http_2, pool_limits, backend, trust_env
         url = URL(url)
         if url.scheme in ("http", "https"):
             return HTTPProxy(
@@ -850,7 +849,7 @@ def _proxies_to_dispatchers(
                 pool_limits=pool_limits,
                 backend=backend,
                 trust_env=trust_env,
-                http_versions=http_versions,
+                http_2=http_2,
             )
         raise ValueError(f"Unknown proxy for {url!r}")
 
diff --git a/httpx/config.py b/httpx/config.py
index a32ae84..cace3c2 100644
--- a/httpx/config.py
+++ b/httpx/config.py
@@ -13,15 +13,10 @@ VerifyTypes = typing.Union[str, bool, ssl.SSLContext]
 TimeoutTypes = typing.Union[
     float, typing.Tuple[float, float, float, float], "TimeoutConfig"
 ]
-HTTPVersionTypes = typing.Union[
-    str, typing.List[str], typing.Tuple[str], "HTTPVersionConfig"
-]
 
 
 USER_AGENT = f"python-httpx/{__version__}"
 
-HTTP_VERSIONS_TO_ALPN_IDENTIFIERS = {"HTTP/1.1": "http/1.1", "HTTP/2": "h2"}
-
 DEFAULT_CIPHERS = ":".join(
     [
         "ECDHE+AESGCM",
@@ -91,43 +86,35 @@ class SSLConfig:
             return self
         return SSLConfig(cert=cert, verify=verify)
 
-    def load_ssl_context(
-        self, http_versions: "HTTPVersionConfig" = None
-    ) -> ssl.SSLContext:
-        http_versions = HTTPVersionConfig() if http_versions is None else http_versions
-
+    def load_ssl_context(self, http_2: bool = False) -> ssl.SSLContext:
         logger.trace(
             f"load_ssl_context "
             f"verify={self.verify!r} "
             f"cert={self.cert!r} "
             f"trust_env={self.trust_env!r} "
-            f"http_versions={http_versions!r}"
+            f"http_2={http_2!r}"
         )
 
         if self.ssl_context is None:
             self.ssl_context = (
-                self.load_ssl_context_verify(http_versions=http_versions)
+                self.load_ssl_context_verify(http_2=http_2)
                 if self.verify
-                else self.load_ssl_context_no_verify(http_versions=http_versions)
+                else self.load_ssl_context_no_verify(http_2=http_2)
             )
 
         assert self.ssl_context is not None
         return self.ssl_context
 
-    def load_ssl_context_no_verify(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def load_ssl_context_no_verify(self, http_2: bool = False) -> ssl.SSLContext:
         """
         Return an SSL context for unverified connections.
         """
-        context = self._create_default_ssl_context(http_versions=http_versions)
+        context = self._create_default_ssl_context(http_2=http_2)
         context.verify_mode = ssl.CERT_NONE
         context.check_hostname = False
         return context
 
-    def load_ssl_context_verify(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def load_ssl_context_verify(self, http_2: bool = False) -> ssl.SSLContext:
         """
         Return an SSL context for verified connections.
         """
@@ -146,7 +133,7 @@ class SSLConfig:
                 "invalid path: {}".format(self.verify)
             )
 
-        context = self._create_default_ssl_context(http_versions=http_versions)
+        context = self._create_default_ssl_context(http_2=http_2)
         context.verify_mode = ssl.CERT_REQUIRED
         context.check_hostname = True
 
@@ -175,9 +162,7 @@ class SSLConfig:
 
         return context
 
-    def _create_default_ssl_context(
-        self, http_versions: "HTTPVersionConfig"
-    ) -> ssl.SSLContext:
+    def _create_default_ssl_context(self, http_2: bool) -> ssl.SSLContext:
         """
         Creates the default SSLContext object that's used for both verified
         and unverified connections.
@@ -191,7 +176,8 @@ class SSLConfig:
         context.set_ciphers(DEFAULT_CIPHERS)
 
         if ssl.HAS_ALPN:
-            context.set_alpn_protocols(http_versions.alpn_identifiers)
+            alpn_idents = ["http/1.1", "h2"] if http_2 else ["http/1.1"]
+            context.set_alpn_protocols(alpn_idents)
 
         if hasattr(context, "keylog_filename"):
             keylogfile = os.environ.get("SSLKEYLOGFILE")
@@ -288,52 +274,6 @@ class TimeoutConfig:
         )
 
 
-class HTTPVersionConfig:
-    """
-    Configure which HTTP protocol versions are supported.
-    """
-
-    def __init__(self, http_versions: HTTPVersionTypes = None):
-        if http_versions is None:
-            http_versions = ["HTTP/1.1", "HTTP/2"]
-
-        if isinstance(http_versions, str):
-            self.http_versions = {http_versions.upper()}
-        elif isinstance(http_versions, HTTPVersionConfig):
-            self.http_versions = http_versions.http_versions
-        elif isinstance(http_versions, typing.Iterable):
-            self.http_versions = {
-                version.upper() if isinstance(version, str) else version
-                for version in http_versions
-            }
-        else:
-            raise TypeError(
-                "HTTP version should be a string or list of strings, "
-                f"but got {type(http_versions)}"
-            )
-
-        for version in self.http_versions:
-            if version not in ("HTTP/1.1", "HTTP/2"):
-                raise ValueError(f"Unsupported HTTP version {version!r}.")
-
-        if not self.http_versions:
-            raise ValueError("HTTP versions cannot be an empty list.")
-
-    @property
-    def alpn_identifiers(self) -> typing.List[str]:
-        """
-        Returns a list of supported ALPN identifiers. (One or more of "http/1.1", "h2").
-        """
-        return [
-            HTTP_VERSIONS_TO_ALPN_IDENTIFIERS[version] for version in self.http_versions
-        ]
-
-    def __repr__(self) -> str:
-        class_name = self.__class__.__name__
-        value = sorted(list(self.http_versions))
-        return f"{class_name}({value!r})"
-
-
 class PoolLimits:
     """
     Limits on the number of connections in a connection pool.
diff --git a/httpx/dispatch/connection.py b/httpx/dispatch/connection.py
index 6694caa..0f05b2e 100644
--- a/httpx/dispatch/connection.py
+++ b/httpx/dispatch/connection.py
@@ -7,8 +7,6 @@ from ..concurrency.base import ConcurrencyBackend
 from ..config import (
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionConfig,
-    HTTPVersionTypes,
     SSLConfig,
     TimeoutConfig,
     TimeoutTypes,
@@ -35,7 +33,7 @@ class HTTPConnection(Dispatcher):
         cert: CertTypes = None,
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
         release_func: typing.Optional[ReleaseCallback] = None,
         uds: typing.Optional[str] = None,
@@ -43,7 +41,7 @@ class HTTPConnection(Dispatcher):
         self.origin = Origin(origin) if isinstance(origin, str) else origin
         self.ssl = SSLConfig(cert=cert, verify=verify, trust_env=trust_env)
         self.timeout = TimeoutConfig(timeout)
-        self.http_versions = HTTPVersionConfig(http_versions)
+        self.http_2 = http_2
         self.backend = AsyncioBackend() if backend is None else backend
         self.release_func = release_func
         self.uds = uds
@@ -119,9 +117,7 @@ class HTTPConnection(Dispatcher):
             return None
 
         # Run the SSL loading in a threadpool, since it may make disk accesses.
-        return await self.backend.run_in_threadpool(
-            ssl.load_ssl_context, self.http_versions
-        )
+        return await self.backend.run_in_threadpool(ssl.load_ssl_context, self.http_2)
 
     async def close(self) -> None:
         logger.trace("close_connection")
diff --git a/httpx/dispatch/connection_pool.py b/httpx/dispatch/connection_pool.py
index 3217330..fc44c41 100644
--- a/httpx/dispatch/connection_pool.py
+++ b/httpx/dispatch/connection_pool.py
@@ -6,7 +6,6 @@ from ..config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     TimeoutConfig,
     TimeoutTypes,
@@ -88,7 +87,7 @@ class ConnectionPool(Dispatcher):
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
         uds: typing.Optional[str] = None,
     ):
@@ -96,7 +95,7 @@ class ConnectionPool(Dispatcher):
         self.cert = cert
         self.timeout = TimeoutConfig(timeout)
         self.pool_limits = pool_limits
-        self.http_versions = http_versions
+        self.http_2 = http_2
         self.is_closed = False
         self.trust_env = trust_env
         self.uds = uds
@@ -150,7 +149,7 @@ class ConnectionPool(Dispatcher):
                 verify=self.verify,
                 cert=self.cert,
                 timeout=self.timeout,
-                http_versions=self.http_versions,
+                http_2=self.http_2,
                 backend=self.backend,
                 release_func=self.release_connection,
                 trust_env=self.trust_env,
diff --git a/httpx/dispatch/proxy_http.py b/httpx/dispatch/proxy_http.py
index 13eb423..c51c009 100644
--- a/httpx/dispatch/proxy_http.py
+++ b/httpx/dispatch/proxy_http.py
@@ -8,7 +8,6 @@ from ..config import (
     DEFAULT_POOL_LIMITS,
     DEFAULT_TIMEOUT_CONFIG,
     CertTypes,
-    HTTPVersionTypes,
     PoolLimits,
     SSLConfig,
     TimeoutTypes,
@@ -47,7 +46,7 @@ class HTTPProxy(ConnectionPool):
         trust_env: bool = None,
         timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
         pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
-        http_versions: HTTPVersionTypes = None,
+        http_2: bool = False,
         backend: ConcurrencyBackend = None,
     ):
 
@@ -58,7 +57,7 @@ class HTTPProxy(ConnectionPool):
             pool_limits=pool_limits,
             backend=backend,
             trust_env=trust_env,
-            http_versions=http_versions,
+            http_2=http_2,
         )
 
         self.proxy_url = URL(proxy_url)
@@ -134,7 +133,7 @@ class HTTPProxy(ConnectionPool):
             cert=self.cert,
             timeout=self.timeout,
             backend=self.backend,
-            http_versions=["HTTP/1.1"],  # Short-lived 'connection'
+            http_2=False,  # Short-lived 'connection'
             trust_env=self.trust_env,
             release_func=self.release_connection,
         )
diff --git a/mkdocs.yml b/mkdocs.yml
index 0ddd8c8..a2a733c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -12,6 +12,7 @@ nav:
     - Introduction: 'index.md'
     - QuickStart: 'quickstart.md'
     - Advanced Usage: 'advanced.md'
+    - HTTP/2 Support: 'http2.md'
     - Environment Variables: 'environment_variables.md'
     - Requests Compatibility: 'compatibility.md'
     - Developer Interface: 'api.md'

HTTP/2 should be off by default.
So...

I'm super excited that we've got an HTTP/2 implementation in here, but we also need to consider *what default behavior we should be aiming for*, and what we should prioritise.

Our HTTP/2 implementation is neccessarily going to be more complex, and less mature than our HTTP/1.1 implementation. Even if that *wasn't* the case, then HTTP/2 infrastructure that we're connecting too is *more* likely to have implementation issue and quirks than HTTP/1.1 versions.

I think we ought to clearly be *prioritizing for reliablity*, while still supporting users that want the more cutting-edge functionality.

I'd suggest that:

* We ought to have a documentation page on HTTP/2, with a brief overview of the primary differences, and motivation as to *why* user might or might not want to switch HTTP/2 support on.
* We ought to tidy up our interface for switching between HTTP versions.

We currently have this...

```python
client = Client(http_versions=["HTTP/1.1", "HTTP/2"])  # Really clunky
client = Client(http_versions=["HTTP/1.1"]) 
client = Client(http_versions=["HTTP/2"])  # Doesn't really make sense - you *might* still end up with an HTTP/1.1 connection.
```

I think we should just switch to...

```python
client = Client(http_2=True)
client = Client(http_2=False)
```

Furthermore, I think the default ought to be false. There's no point in exposing our users to this class of issues https://github.com/encode/httpx/issues?q=is%3Aissue+is%3Aopen+label%3Ahttp%2F2 *as our default behaviour*, but we can still make it easy for our users to upgrade to the HTTP/2 implementation.
diff --git a/tests/client/test_proxies.py b/tests/client/test_proxies.py
index fc1e57a..ede15a8 100644
--- a/tests/client/test_proxies.py
+++ b/tests/client/test_proxies.py
@@ -36,7 +36,6 @@ def test_proxies_has_same_properties_as_dispatch():
         cert="/path/to/cert",
         trust_env=False,
         timeout=30,
-        http_versions=["HTTP/1.1"],
     )
     pool = client.dispatch
     proxy = client.proxies["all"]
@@ -49,7 +48,6 @@ def test_proxies_has_same_properties_as_dispatch():
         "cert",
         "timeout",
         "pool_limits",
-        "http_versions",
         "backend",
     ]:
         assert getattr(pool, prop) == getattr(proxy, prop)
diff --git a/tests/dispatch/test_http2.py b/tests/dispatch/test_http2.py
index 0c8c917..86dcc8f 100644
--- a/tests/dispatch/test_http2.py
+++ b/tests/dispatch/test_http2.py
@@ -27,7 +27,7 @@ def app(request):
 async def test_http2_get_request():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.get("http://example.org")
 
     assert response.status_code == 200
@@ -38,7 +38,7 @@ async def test_http2_get_request():
 async def test_http2_post_request():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.post("http://example.org", data=b"<data>")
 
     assert response.status_code == 200
@@ -54,7 +54,7 @@ async def test_http2_large_post_request():
     backend = MockHTTP2Backend(app=app)
 
     data = b"a" * 100000
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response = await client.post("http://example.org", data=data)
     assert response.status_code == 200
     assert json.loads(response.content) == {
@@ -68,7 +68,7 @@ async def test_http2_large_post_request():
 async def test_http2_multiple_requests():
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response_1 = await client.get("http://example.org/1")
         response_2 = await client.get("http://example.org/2")
         response_3 = await client.get("http://example.org/3")
@@ -91,7 +91,7 @@ async def test_http2_reconnect():
     """
     backend = MockHTTP2Backend(app=app)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         response_1 = await client.get("http://example.org/1")
         backend.server.close_connection = True
         response_2 = await client.get("http://example.org/2")
@@ -106,7 +106,7 @@ async def test_http2_reconnect():
 async def test_http2_settings_in_handshake(backend):
     backend = MockHTTP2Backend(app=app, backend=backend)
 
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         await client.get("http://example.org")
 
     h2_conn = backend.server.conn
@@ -139,7 +139,7 @@ async def test_http2_settings_in_handshake(backend):
 
 
 async def test_http2_live_request(backend):
-    async with Client(backend=backend) as client:
+    async with Client(backend=backend, http_2=True) as client:
         try:
             resp = await client.get("https://nghttp2.org/httpbin/anything")
         except Timeout:
diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py
index da43987..52828da 100644
--- a/tests/test_concurrency.py
+++ b/tests/test_concurrency.py
@@ -1,7 +1,7 @@
 import pytest
 import trio
 
-from httpx import AsyncioBackend, HTTPVersionConfig, SSLConfig, TimeoutConfig
+from httpx import AsyncioBackend, SSLConfig, TimeoutConfig
 from httpx.concurrency.trio import TrioBackend
 from tests.concurrency import run_concurrently
 
@@ -40,7 +40,7 @@ async def read_response(stream, timeout: float, should_contain: bytes) -> bytes:
     ],
 )
 async def test_start_tls_on_tcp_socket_stream(https_server, backend, get_cipher):
-    ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig())
+    ctx = SSLConfig().load_ssl_context_no_verify()
     timeout = TimeoutConfig(5)
 
     stream = await backend.open_tcp_stream(
@@ -72,7 +72,7 @@ async def test_start_tls_on_tcp_socket_stream(https_server, backend, get_cipher)
     ],
 )
 async def test_start_tls_on_uds_socket_stream(https_uds_server, backend, get_cipher):
-    ctx = SSLConfig().load_ssl_context_no_verify(HTTPVersionConfig())
+    ctx = SSLConfig().load_ssl_context_no_verify()
     timeout = TimeoutConfig(5)
 
     stream = await backend.open_uds_stream(
diff --git a/tests/test_config.py b/tests/test_config.py
index 6f8d808..1835ec7 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -118,46 +118,6 @@ def test_ssl_repr():
     assert repr(ssl) == "SSLConfig(cert=None, verify=False)"
 
 
-def test_http_versions_repr():
-    http_versions = httpx.HTTPVersionConfig()
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1', 'HTTP/2'])"
-
-
-def test_http_versions_from_string():
-    http_versions = httpx.HTTPVersionConfig("HTTP/1.1")
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_http_versions_from_list():
-    http_versions = httpx.HTTPVersionConfig(["http/1.1"])
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_http_versions_from_config():
-    http_versions = httpx.HTTPVersionConfig(httpx.HTTPVersionConfig("HTTP/1.1"))
-    assert repr(http_versions) == "HTTPVersionConfig(['HTTP/1.1'])"
-
-
-def test_invalid_http_version():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig("HTTP/9")
-
-
-def test_invalid_http_version_type():
-    with pytest.raises(TypeError):
-        httpx.HTTPVersionConfig(123)
-
-
-def test_invalid_http_version_list_type():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig([123])
-
-
-def test_empty_http_version():
-    with pytest.raises(ValueError):
-        httpx.HTTPVersionConfig([])
-
-
 def test_limits_repr():
     limits = httpx.PoolLimits(hard_limit=100)
     assert repr(limits) == "PoolLimits(soft_limit=None, hard_limit=100)"
diff --git a/tests/test_multipart.py b/tests/test_multipart.py
index 3936a05..b5e2290 100644
--- a/tests/test_multipart.py
+++ b/tests/test_multipart.py
@@ -10,7 +10,6 @@ from httpx import (
     CertTypes,
     Client,
     Dispatcher,
-    HTTPVersionTypes,
     Request,
     Response,
     TimeoutTypes,
@@ -26,7 +25,6 @@ class MockDispatch(Dispatcher):
         verify: VerifyTypes = None,
         cert: CertTypes = None,
         timeout: TimeoutTypes = None,
-        http_versions: HTTPVersionTypes = None,
     ) -> Response:
         content = await request.read()
         return Response(200, content=content)

pip install -e .[dev]
parse_log_pytest
requirements.txt
apt-get update apt-get install -y gcc
3.8
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aspy.refactor-imports==3.0.2
attrs==25.3.0
autoflake==2.3.1
babel==2.17.0
backrefs==5.7.post1
black==24.8.0
brotlipy==0.7.0
certifi==2025.1.31
cffi==1.17.1
chardet==3.0.4
charset-normalizer==3.4.1
click==8.1.8
colorama==0.4.6
coverage==7.6.1
cryptography==44.0.2
exceptiongroup==1.2.2
flake8==7.1.2
flake8-bugbear==24.12.12
flake8-pie==0.16.0
ghp-import==2.1.0
h11==0.8.1
h2==3.2.0
hpack==3.0.0
hstspreload==2025.1.1
-e git+https://github.com/encode/httpx.git@12d00b238e837a96271d7b07b8c3b456bd82fe0c#egg=httpx
hyperframe==5.2.0
idna==2.10
importlib_metadata==8.5.0
iniconfig==2.1.0
isort==5.13.2
Jinja2==3.1.6
Markdown==3.7
MarkupSafe==2.1.5
mccabe==0.7.0
mergedeep==1.3.4
mkautodoc==0.2.0
mkdocs==1.6.1
mkdocs-get-deps==0.2.0
mkdocs-material==9.6.10
mkdocs-material-extensions==1.3.1
mypy==1.14.1
mypy-extensions==1.0.0
outcome==1.3.0.post0
packaging==24.2
paginate==0.5.7
pathspec==0.12.1
platformdirs==4.3.6
pluggy==1.5.0
pycodestyle==2.12.1
pycparser==2.22
pyflakes==3.2.0
Pygments==2.19.1
pymdown-extensions==10.14.3
pytest==8.3.5
pytest-asyncio==0.24.0
pytest-cov==5.0.0
pytest-trio==0.8.0
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
pyyaml_env_tag==0.1
requests==2.32.3
rfc3986==1.5.0
seed-isort-config==2.2.0
six==1.17.0
sniffio==1.3.1
sortedcontainers==2.4.0
tomli==2.2.1
trio==0.27.0
trustme==1.1.0
typing_extensions==4.13.0
urllib3==2.2.3
uvicorn==0.33.0
watchdog==4.0.2
zipp==3.20.2

name: httpx
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=24.2=py38h06a4308_0
  - python=3.8.20=he870216_0
  - readline=8.2=h5eee18b_0
  - setuptools=75.1.0=py38h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.44.0=py38h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aspy-refactor-imports==3.0.2
      - attrs==25.3.0
      - autoflake==2.3.1
      - babel==2.17.0
      - backrefs==5.7.post1
      - black==24.8.0
      - brotlipy==0.7.0
      - certifi==2025.1.31
      - cffi==1.17.1
      - chardet==3.0.4
      - charset-normalizer==3.4.1
      - click==8.1.8
      - colorama==0.4.6
      - coverage==7.6.1
      - cryptography==44.0.2
      - exceptiongroup==1.2.2
      - flake8==7.1.2
      - flake8-bugbear==24.12.12
      - flake8-pie==0.16.0
      - ghp-import==2.1.0
      - h11==0.8.1
      - h2==3.2.0
      - hpack==3.0.0
      - hstspreload==2025.1.1
      - hyperframe==5.2.0
      - idna==2.10
      - importlib-metadata==8.5.0
      - iniconfig==2.1.0
      - isort==5.13.2
      - jinja2==3.1.6
      - markdown==3.7
      - markupsafe==2.1.5
      - mccabe==0.7.0
      - mergedeep==1.3.4
      - mkautodoc==0.2.0
      - mkdocs==1.6.1
      - mkdocs-get-deps==0.2.0
      - mkdocs-material==9.6.10
      - mkdocs-material-extensions==1.3.1
      - mypy==1.14.1
      - mypy-extensions==1.0.0
      - outcome==1.3.0.post0
      - packaging==24.2
      - paginate==0.5.7
      - pathspec==0.12.1
      - platformdirs==4.3.6
      - pluggy==1.5.0
      - pycodestyle==2.12.1
      - pycparser==2.22
      - pyflakes==3.2.0
      - pygments==2.19.1
      - pymdown-extensions==10.14.3
      - pytest==8.3.5
      - pytest-asyncio==0.24.0
      - pytest-cov==5.0.0
      - pytest-trio==0.8.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.2
      - pyyaml-env-tag==0.1
      - requests==2.32.3
      - rfc3986==1.5.0
      - seed-isort-config==2.2.0
      - six==1.17.0
      - sniffio==1.3.1
      - sortedcontainers==2.4.0
      - tomli==2.2.1
      - trio==0.27.0
      - trustme==1.1.0
      - typing-extensions==4.13.0
      - urllib3==2.2.3
      - uvicorn==0.33.0
      - watchdog==4.0.2
      - zipp==3.20.2
prefix: /opt/conda/envs/httpx

tests/dispatch/test_http2.py::test_http2_get_request tests/dispatch/test_http2.py::test_http2_post_request tests/dispatch/test_http2.py::test_http2_large_post_request tests/dispatch/test_http2.py::test_http2_multiple_requests tests/dispatch/test_http2.py::test_http2_reconnect tests/dispatch/test_http2.py::test_http2_settings_in_handshake[AsyncioBackend] tests/dispatch/test_http2.py::test_http2_settings_in_handshake[TrioBackend] tests/dispatch/test_http2.py::test_http2_live_request[AsyncioBackend] tests/dispatch/test_http2.py::test_http2_live_request[TrioBackend]
tests/test_concurrency.py::test_start_tls_on_tcp_socket_stream[backend0-get_asyncio_cipher] tests/test_concurrency.py::test_start_tls_on_tcp_socket_stream[backend1-get_trio_cipher] tests/test_concurrency.py::test_start_tls_on_uds_socket_stream[backend0-get_asyncio_cipher] tests/test_concurrency.py::test_start_tls_on_uds_socket_stream[backend1-get_trio_cipher]
tests/client/test_proxies.py::test_proxies_parameter[http://127.0.0.1-expected_proxies0] tests/client/test_proxies.py::test_proxies_parameter[proxies1-expected_proxies1] tests/client/test_proxies.py::test_proxies_parameter[proxies2-expected_proxies2] tests/client/test_proxies.py::test_proxies_parameter[proxies3-expected_proxies3] tests/client/test_proxies.py::test_proxies_parameter[proxies4-expected_proxies4] tests/client/test_proxies.py::test_proxies_has_same_properties_as_dispatch tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-None-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies1-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies2-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies3-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com:443-proxies4-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies5-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies6-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies7-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies8-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies9-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies10-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com:8080-proxies11-http://[::1]] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com:8080-proxies12-None] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies13-http://[::1]:4] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies14-http://[::1]:3] tests/client/test_proxies.py::test_dispatcher_for_request[http://example.com-proxies15-http://[::1]:2] tests/client/test_proxies.py::test_unsupported_proxy_scheme tests/test_concurrency.py::test_concurrent_read[AsyncioBackend] tests/test_concurrency.py::test_concurrent_read[TrioBackend] tests/test_config.py::test_load_ssl_config tests/test_config.py::test_load_ssl_config_verify_non_existing_path tests/test_config.py::test_load_ssl_config_verify_existing_file tests/test_config.py::test_load_ssl_config_verify_env_file[SSL_CERT_FILE] tests/test_config.py::test_load_ssl_config_verify_env_file[SSL_CERT_DIR] tests/test_config.py::test_load_ssl_config_verify_directory tests/test_config.py::test_load_ssl_config_cert_and_key tests/test_config.py::test_load_ssl_config_cert_and_encrypted_key[password0] tests/test_config.py::test_load_ssl_config_cert_and_encrypted_key[password1] tests/test_config.py::test_load_ssl_config_cert_and_key_invalid_password tests/test_config.py::test_load_ssl_config_cert_without_key_raises tests/test_config.py::test_load_ssl_config_no_verify tests/test_config.py::test_load_ssl_context tests/test_config.py::test_ssl_repr tests/test_config.py::test_limits_repr tests/test_config.py::test_ssl_eq tests/test_config.py::test_limits_eq tests/test_config.py::test_timeout_eq tests/test_config.py::test_timeout_from_nothing tests/test_config.py::test_timeout_from_none tests/test_config.py::test_timeout_from_one_none_value tests/test_config.py::test_timeout_from_tuple tests/test_config.py::test_timeout_from_config_instance tests/test_config.py::test_timeout_repr tests/test_config.py::test_ssl_config_support_for_keylog_file tests/test_multipart.py::test_multipart[abc-abc0] tests/test_multipart.py::test_multipart[abc-abc1] tests/test_multipart.py::test_multipart_invalid_key[abc] tests/test_multipart.py::test_multipart_invalid_key[1] tests/test_multipart.py::test_multipart_invalid_key[2.3] tests/test_multipart.py::test_multipart_invalid_key[None] tests/test_multipart.py::test_multipart_invalid_value[1] tests/test_multipart.py::test_multipart_invalid_value[2.3] tests/test_multipart.py::test_multipart_invalid_value[None] tests/test_multipart.py::test_multipart_invalid_value[value3] tests/test_multipart.py::test_multipart_invalid_value[value4] tests/test_multipart.py::test_multipart_file_tuple tests/test_multipart.py::test_multipart_encode tests/test_multipart.py::test_multipart_encode_files_allows_filenames_as_none tests/test_multipart.py::test_multipart_encode_files_guesses_correct_content_type[example.json-application/json] tests/test_multipart.py::test_multipart_encode_files_guesses_correct_content_type[example.txt-text/plain] tests/test_multipart.py::test_multipart_encode_files_guesses_correct_content_type[no-extension-application/octet-stream] tests/test_multipart.py::test_multipart_encode_files_allows_str_content tests/test_multipart.py::TestHeaderParamHTML5Formatting::test_unicode tests/test_multipart.py::TestHeaderParamHTML5Formatting::test_ascii tests/test_multipart.py::TestHeaderParamHTML5Formatting::test_unicode_escape tests/test_multipart.py::TestHeaderParamHTML5Formatting::test_unicode_with_control_character
httpx/api.py httpx/__init__.py docs/index.md docs/http2.md httpx/client.py httpx/dispatch/connection_pool.py httpx/dispatch/proxy_http.py mkdocs.yml docs/advanced.md httpx/dispatch/connection.py httpx/config.py
httpx/api.py httpx/__init__.py docs/index.md docs/http2.md httpx/client.py httpx/dispatch/connection_pool.py httpx/dispatch/proxy_http.py mkdocs.yml docs/advanced.md httpx/dispatch/connection.py httpx/config.py