Repository: miketheman/pytest-socket (language: python)

Issue:
pytest-socket raises IndexError when used with httpx
pytest-socket raises IndexError when used with httpx:

```python
cls = <class 'pytest_socket.disable_socket.<locals>.GuardedSocket'>, args = ()
kwargs = {'family': <AddressFamily.AF_INET: 2>, 'proto': 6, 'type': <SocketKind.SOCK_STREAM: 1>}

    def __new__(cls, *args, **kwargs):
        try:
>           is_unix_socket = args[0] == socket.AF_UNIX
E           IndexError: tuple index out of range

.venv/lib/python3.9/site-packages/pytest_socket.py:89: IndexError
```

<details>
<summary>See full stack trace</summary>
<br>

```python
.venv/lib/python3.9/site-packages/httpx/_client.py:1736: in get
    return await self.request(
.venv/lib/python3.9/site-packages/httpx/_client.py:1513: in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
.venv/lib/python3.9/site-packages/httpx/_client.py:1600: in send
    response = await self._send_handling_auth(
.venv/lib/python3.9/site-packages/httpx/_client.py:1628: in _send_handling_auth
    response = await self._send_handling_redirects(
.venv/lib/python3.9/site-packages/httpx/_client.py:1665: in _send_handling_redirects
    response = await self._send_single_request(request)
.venv/lib/python3.9/site-packages/httpx/_client.py:1702: in _send_single_request
    response = await transport.handle_async_request(request)
.venv/lib/python3.9/site-packages/httpx/_transports/asgi.py:152: in handle_async_request
    await self.app(scope, receive, send)
...
.venv/lib/python3.9/site-packages/httpx/_client.py:1513: in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
.venv/lib/python3.9/site-packages/httpx/_client.py:1600: in send
    response = await self._send_handling_auth(
.venv/lib/python3.9/site-packages/httpx/_client.py:1628: in _send_handling_auth
    response = await self._send_handling_redirects(
.venv/lib/python3.9/site-packages/httpx/_client.py:1665: in _send_handling_redirects
    response = await self._send_single_request(request)
.venv/lib/python3.9/site-packages/httpx/_client.py:1702: in _send_single_request
    response = await transport.handle_async_request(request)
.venv/lib/python3.9/site-packages/httpx/_transports/default.py:291: in handle_async_request
    resp = await self._pool.handle_async_request(req)
.venv/lib/python3.9/site-packages/httpcore/_async/connection_pool.py:248: in handle_async_request
    raise exc
.venv/lib/python3.9/site-packages/httpcore/_async/connection_pool.py:232: in handle_async_request
    response = await connection.handle_async_request(request)
.venv/lib/python3.9/site-packages/httpcore/_async/connection.py:90: in handle_async_request
    raise exc
.venv/lib/python3.9/site-packages/httpcore/_async/connection.py:67: in handle_async_request
    stream = await self._connect(request)
.venv/lib/python3.9/site-packages/httpcore/_async/connection.py:115: in _connect
    stream = await self._network_backend.connect_tcp(**kwargs)
.venv/lib/python3.9/site-packages/httpcore/backends/auto.py:23: in connect_tcp
    return await self._backend.connect_tcp(
.venv/lib/python3.9/site-packages/httpcore/backends/asyncio.py:97: in connect_tcp
    stream: anyio.abc.ByteStream = await anyio.connect_tcp(
.venv/lib/python3.9/site-packages/anyio/_core/_sockets.py:180: in connect_tcp
    await event.wait()
.venv/lib/python3.9/site-packages/anyio/_backends/_asyncio.py:567: in __aexit__
    raise exceptions[0]
.venv/lib/python3.9/site-packages/anyio/_core/_sockets.py:127: in try_connect
    stream = await asynclib.connect_tcp(remote_host, remote_port, local_address)
.venv/lib/python3.9/site-packages/anyio/_backends/_asyncio.py:1499: in connect_tcp
    await get_running_loop().create_connection(StreamProtocol, host, port,
/usr/lib/python3.9/asyncio/base_events.py:1041: in create_connection
    sock = await self._connect_sock(
/usr/lib/python3.9/asyncio/base_events.py:938: in _connect_sock
    sock = socket.socket(family=family, type=type_, proto=proto)
```
</details>

I'm not sure exactly why this happens but I'm guessing it is somehow related to anyio rather than httpx. You can reproduce the issue with this code:

```python
import pytest
import httpx


@pytest.fixture(autouse=True)
def anyio_backend():
    return "asyncio"

async def test_httpx():
    async with httpx.AsyncClient() as client:
        await client.get("http://www.example.com/")
```


Discussion / hints:

Fix patch:
diff --git a/pyproject.toml b/pyproject.toml
index 5828d45..0e9734a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -31,7 +31,7 @@ classifiers = [
 ]
 
 [tool.poetry.dependencies]
-python = "^3.6"
+python = "^3.6.2"
 pytest = ">=3.6.3"
 
 [tool.poetry.dev-dependencies]
@@ -42,6 +42,7 @@ pytest-flake8 = "^1.0.4"
 asynctest = "^0.13.0"
 requests = "^2.26.0"
 starlette = "^0.14.2"
+httpx = "^0.21.1"
 
 [tool.poetry.plugins.pytest11]
 socket = 'pytest_socket'


Test patch:
diff --git a/pytest_socket.py b/pytest_socket.py
index 5e4ca3c..053c18d 100644
--- a/pytest_socket.py
+++ b/pytest_socket.py
@@ -87,7 +87,7 @@ class GuardedSocket(socket.socket):
         def __new__(cls, *args, **kwargs):
             try:
                 is_unix_socket = args[0] == socket.AF_UNIX
-            except AttributeError:
+            except (AttributeError, IndexError):
                 # AF_UNIX not supported on Windows https://bugs.python.org/issue33408
                 is_unix_socket = False
 
diff --git a/tests/test_async.py b/tests/test_async.py
index 963ba73..e521e59 100644
--- a/tests/test_async.py
+++ b/tests/test_async.py
@@ -1,7 +1,7 @@
 import socket
 
 import pytest
-
+from test_socket import assert_socket_blocked
 
 unix_sockets_only = pytest.mark.skipif(
     not hasattr(socket, "AF_UNIX"),
@@ -54,3 +54,22 @@ def test_app():
     """)
     result = testdir.runpytest("--verbose", "--disable-socket", "--allow-unix-socket")
     result.assert_outcomes(passed=1, skipped=0, failed=0)
+
+
+@unix_sockets_only
+def test_httpx_fails(testdir):
+    testdir.makepyfile("""
+        import pytest
+        import httpx
+
+
+        @pytest.fixture(autouse=True)
+        def anyio_backend():
+            return "asyncio"
+
+        async def test_httpx():
+            async with httpx.AsyncClient() as client:
+                await client.get("http://www.example.com/")
+    """)
+    result = testdir.runpytest("--verbose", "--disable-socket", "--allow-unix-socket")
+    assert_socket_blocked(result)