We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
web3.auto raises unclear exception if no client is live
* Version: 4.0.0-beta.1
* OS: linux


### What was wrong?

If no client is live, I expect w3 to return as `None` in this case, but instead I get an exception.
```
from web3.auto import w3
```

cc @Sebohe 

> ~/code/ethtoken/ethtoken/main.py in eip20_token(address, w3, **kwargs)
>      23     '''
>      24     if w3 is None:
> ---> 25         from web3.auto import w3
>      26         if w3 is None:
>      27             raise RuntimeError("Could not auto-detect web3 connection, please supply it as arg w3")
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/__init__.py in <module>()
>       2 
>       3 for connector in ('ipc', 'http'):
> ----> 4     connection = importlib.import_module('web3.auto.' + connector)
>       5     if connection.w3:
>       6         w3 = connection.w3
> 
> /usr/lib/python3.5/importlib/__init__.py in import_module(name, package)
>     124                 break
>     125             level += 1
> --> 126     return _bootstrap._gcd_import(name[level:], package, level)
>     127 
>     128 
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/ipc.py in <module>()
>      14 
>      15 
> ---> 16 w3 = connect()
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/ipc.py in connect()
>       8 def connect():
>       9     w3 = Web3(IPCProvider(get_default_ipc_path()))
> ---> 10     if w3.isConnected():
>      11         return w3
>      12 
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/main.py in isConnected(self)
>     155     def isConnected(self):
>     156         for provider in self.providers:
> --> 157             if provider.isConnected():
>     158                 return True
>     159         else:
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/base.py in isConnected(self)
>      73     def isConnected(self):
>      74         try:
> ---> 75             response = self.make_request('web3_clientVersion', [])
>      76         except IOError:
>      77             return False
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in make_request(self, method, params)
>     139         request = self.encode_rpc_request(method, params)
>     140 
> --> 141         with self._lock, self._socket as sock:
>     142             sock.sendall(request)
>     143             raw_response = b""
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in __enter__(self)
>      37     def __enter__(self):
>      38         if not self.sock:
> ---> 39             self.sock = get_ipc_socket(self.ipc_path)
>      40         return self.sock
>      41 
> 
> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in get_ipc_socket(ipc_path, timeout)
>      24     else:
>      25         sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
> ---> 26         sock.connect(ipc_path)
>      27         sock.settimeout(timeout)
>      28         return sock
> 
> TypeError: a bytes-like object is required, not 'NoneType'


### How can it be fixed?

* Add a new test to verify the situation, and prevent regressions
* `isConnected` should short-circuit with something like: `if self.ipc_path is None: return False`


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `web3/providers/ipc.py`
Content:
```
1 import os
2 import socket
3 import sys
4 import threading
5 
6 try:
7     from json import JSONDecodeError
8 except ImportError:
9     JSONDecodeError = ValueError
10 
11 from web3.utils.threads import (
12     Timeout,
13 )
14 
15 from .base import JSONBaseProvider
16 
17 
18 def get_ipc_socket(ipc_path, timeout=0.1):
19     if sys.platform == 'win32':
20         # On Windows named pipe is used. Simulate socket with it.
21         from web3.utils.windows import NamedPipe
22 
23         return NamedPipe(ipc_path)
24     else:
25         sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
26         sock.connect(ipc_path)
27         sock.settimeout(timeout)
28         return sock
29 
30 
31 class PersistantSocket(object):
32     sock = None
33 
34     def __init__(self, ipc_path):
35         self.ipc_path = ipc_path
36 
37     def __enter__(self):
38         if not self.sock:
39             self.sock = get_ipc_socket(self.ipc_path)
40         return self.sock
41 
42     def __exit__(self, exc_type, exc_value, traceback):
43         # only close the socket if there was an error
44         if exc_value is not None:
45             try:
46                 self.sock.close()
47             except Exception:
48                 pass
49             self.sock = None
50 
51 
52 def get_default_ipc_path(testnet=False):
53     if testnet:
54         testnet = "testnet"
55     else:
56         testnet = ""
57 
58     if sys.platform == 'darwin':
59         ipc_path = os.path.expanduser(os.path.join(
60             "~",
61             "Library",
62             "Ethereum",
63             testnet,
64             "geth.ipc"
65         ))
66         if os.path.exists(ipc_path):
67             return ipc_path
68 
69         ipc_path = os.path.expanduser(os.path.join(
70             "~",
71             "Library",
72             "Application Support",
73             "io.parity.ethereum",
74             "jsonrpc.ipc"
75         ))
76         if os.path.exists(ipc_path):
77             return ipc_path
78 
79     elif sys.platform.startswith('linux'):
80         ipc_path = os.path.expanduser(os.path.join(
81             "~",
82             ".ethereum",
83             testnet,
84             "geth.ipc"
85         ))
86         if os.path.exists(ipc_path):
87             return ipc_path
88 
89         ipc_path = os.path.expanduser(os.path.join(
90             "~",
91             ".local",
92             "share",
93             "io.parity.ethereum",
94             "jsonrpc.ipc"
95         ))
96         if os.path.exists(ipc_path):
97             return ipc_path
98 
99     elif sys.platform == 'win32':
100         ipc_path = os.path.join(
101             "\\\\",
102             ".",
103             "pipe",
104             "geth.ipc"
105         )
106         if os.path.exists(ipc_path):
107             return ipc_path
108 
109         ipc_path = os.path.join(
110             "\\\\",
111             ".",
112             "pipe",
113             "jsonrpc.ipc"
114         )
115         if os.path.exists(ipc_path):
116             return ipc_path
117 
118     else:
119         raise ValueError(
120             "Unsupported platform '{0}'.  Only darwin/linux2/win32 are "
121             "supported.  You must specify the ipc_path".format(sys.platform)
122         )
123 
124 
125 class IPCProvider(JSONBaseProvider):
126     _socket = None
127 
128     def __init__(self, ipc_path=None, testnet=False, *args, **kwargs):
129         if ipc_path is None:
130             self.ipc_path = get_default_ipc_path(testnet)
131         else:
132             self.ipc_path = ipc_path
133 
134         self._lock = threading.Lock()
135         self._socket = PersistantSocket(self.ipc_path)
136         super(IPCProvider, self).__init__(*args, **kwargs)
137 
138     def make_request(self, method, params):
139         request = self.encode_rpc_request(method, params)
140 
141         with self._lock, self._socket as sock:
142             sock.sendall(request)
143             raw_response = b""
144             with Timeout(10) as timeout:
145                 while True:
146                     try:
147                         raw_response += sock.recv(4096)
148                     except socket.timeout:
149                         timeout.sleep(0)
150                         continue
151                     if raw_response == b"":
152                         timeout.sleep(0)
153                     else:
154                         try:
155                             response = self.decode_rpc_response(raw_response)
156                         except JSONDecodeError:
157                             timeout.sleep(0)
158                             continue
159                         else:
160                             return response
161
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py
--- a/web3/providers/ipc.py
+++ b/web3/providers/ipc.py
@@ -35,6 +35,9 @@
         self.ipc_path = ipc_path
 
     def __enter__(self):
+        if not self.ipc_path:
+            raise FileNotFoundError("cannot connect to IPC socket at path: %r" % self.ipc_path)
+
         if not self.sock:
             self.sock = get_ipc_socket(self.ipc_path)
         return self.sock

{"golden_diff": "diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py\n--- a/web3/providers/ipc.py\n+++ b/web3/providers/ipc.py\n@@ -35,6 +35,9 @@\n         self.ipc_path = ipc_path\n \n     def __enter__(self):\n+        if not self.ipc_path:\n+            raise FileNotFoundError(\"cannot connect to IPC socket at path: %r\" % self.ipc_path)\n+\n         if not self.sock:\n             self.sock = get_ipc_socket(self.ipc_path)\n         return self.sock\n", "issue": "web3.auto raises unclear exception if no client is live\n* Version: 4.0.0-beta.1\r\n* OS: linux\r\n\r\n\r\n### What was wrong?\r\n\r\nIf no client is live, I expect w3 to return as `None` in this case, but instead I get an exception.\r\n```\r\nfrom web3.auto import w3\r\n```\r\n\r\ncc @Sebohe \r\n\r\n> ~/code/ethtoken/ethtoken/main.py in eip20_token(address, w3, **kwargs)\r\n>      23     '''\r\n>      24     if w3 is None:\r\n> ---> 25         from web3.auto import w3\r\n>      26         if w3 is None:\r\n>      27             raise RuntimeError(\"Could not auto-detect web3 connection, please supply it as arg w3\")\r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/__init__.py in <module>()\r\n>       2 \r\n>       3 for connector in ('ipc', 'http'):\r\n> ----> 4     connection = importlib.import_module('web3.auto.' + connector)\r\n>       5     if connection.w3:\r\n>       6         w3 = connection.w3\r\n> \r\n> /usr/lib/python3.5/importlib/__init__.py in import_module(name, package)\r\n>     124                 break\r\n>     125             level += 1\r\n> --> 126     return _bootstrap._gcd_import(name[level:], package, level)\r\n>     127 \r\n>     128 \r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/ipc.py in <module>()\r\n>      14 \r\n>      15 \r\n> ---> 16 w3 = connect()\r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/auto/ipc.py in connect()\r\n>       8 def connect():\r\n>       9     w3 = Web3(IPCProvider(get_default_ipc_path()))\r\n> ---> 10     if w3.isConnected():\r\n>      11         return w3\r\n>      12 \r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/main.py in isConnected(self)\r\n>     155     def isConnected(self):\r\n>     156         for provider in self.providers:\r\n> --> 157             if provider.isConnected():\r\n>     158                 return True\r\n>     159         else:\r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/base.py in isConnected(self)\r\n>      73     def isConnected(self):\r\n>      74         try:\r\n> ---> 75             response = self.make_request('web3_clientVersion', [])\r\n>      76         except IOError:\r\n>      77             return False\r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in make_request(self, method, params)\r\n>     139         request = self.encode_rpc_request(method, params)\r\n>     140 \r\n> --> 141         with self._lock, self._socket as sock:\r\n>     142             sock.sendall(request)\r\n>     143             raw_response = b\"\"\r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in __enter__(self)\r\n>      37     def __enter__(self):\r\n>      38         if not self.sock:\r\n> ---> 39             self.sock = get_ipc_socket(self.ipc_path)\r\n>      40         return self.sock\r\n>      41 \r\n> \r\n> ~/code/ethtoken/venv/lib/python3.5/site-packages/web3/providers/ipc.py in get_ipc_socket(ipc_path, timeout)\r\n>      24     else:\r\n>      25         sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\r\n> ---> 26         sock.connect(ipc_path)\r\n>      27         sock.settimeout(timeout)\r\n>      28         return sock\r\n> \r\n> TypeError: a bytes-like object is required, not 'NoneType'\r\n\r\n\r\n### How can it be fixed?\r\n\r\n* Add a new test to verify the situation, and prevent regressions\r\n* `isConnected` should short-circuit with something like: `if self.ipc_path is None: return False`\r\n\n", "before_files": [{"content": "import os\nimport socket\nimport sys\nimport threading\n\ntry:\n    from json import JSONDecodeError\nexcept ImportError:\n    JSONDecodeError = ValueError\n\nfrom web3.utils.threads import (\n    Timeout,\n)\n\nfrom .base import JSONBaseProvider\n\n\ndef get_ipc_socket(ipc_path, timeout=0.1):\n    if sys.platform == 'win32':\n        # On Windows named pipe is used. Simulate socket with it.\n        from web3.utils.windows import NamedPipe\n\n        return NamedPipe(ipc_path)\n    else:\n        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        sock.connect(ipc_path)\n        sock.settimeout(timeout)\n        return sock\n\n\nclass PersistantSocket(object):\n    sock = None\n\n    def __init__(self, ipc_path):\n        self.ipc_path = ipc_path\n\n    def __enter__(self):\n        if not self.sock:\n            self.sock = get_ipc_socket(self.ipc_path)\n        return self.sock\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        # only close the socket if there was an error\n        if exc_value is not None:\n            try:\n                self.sock.close()\n            except Exception:\n                pass\n            self.sock = None\n\n\ndef get_default_ipc_path(testnet=False):\n    if testnet:\n        testnet = \"testnet\"\n    else:\n        testnet = \"\"\n\n    if sys.platform == 'darwin':\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \"Library\",\n            \"Ethereum\",\n            testnet,\n            \"geth.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \"Library\",\n            \"Application Support\",\n            \"io.parity.ethereum\",\n            \"jsonrpc.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    elif sys.platform.startswith('linux'):\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \".ethereum\",\n            testnet,\n            \"geth.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \".local\",\n            \"share\",\n            \"io.parity.ethereum\",\n            \"jsonrpc.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    elif sys.platform == 'win32':\n        ipc_path = os.path.join(\n            \"\\\\\\\\\",\n            \".\",\n            \"pipe\",\n            \"geth.ipc\"\n        )\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.join(\n            \"\\\\\\\\\",\n            \".\",\n            \"pipe\",\n            \"jsonrpc.ipc\"\n        )\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    else:\n        raise ValueError(\n            \"Unsupported platform '{0}'.  Only darwin/linux2/win32 are \"\n            \"supported.  You must specify the ipc_path\".format(sys.platform)\n        )\n\n\nclass IPCProvider(JSONBaseProvider):\n    _socket = None\n\n    def __init__(self, ipc_path=None, testnet=False, *args, **kwargs):\n        if ipc_path is None:\n            self.ipc_path = get_default_ipc_path(testnet)\n        else:\n            self.ipc_path = ipc_path\n\n        self._lock = threading.Lock()\n        self._socket = PersistantSocket(self.ipc_path)\n        super(IPCProvider, self).__init__(*args, **kwargs)\n\n    def make_request(self, method, params):\n        request = self.encode_rpc_request(method, params)\n\n        with self._lock, self._socket as sock:\n            sock.sendall(request)\n            raw_response = b\"\"\n            with Timeout(10) as timeout:\n                while True:\n                    try:\n                        raw_response += sock.recv(4096)\n                    except socket.timeout:\n                        timeout.sleep(0)\n                        continue\n                    if raw_response == b\"\":\n                        timeout.sleep(0)\n                    else:\n                        try:\n                            response = self.decode_rpc_response(raw_response)\n                        except JSONDecodeError:\n                            timeout.sleep(0)\n                            continue\n                        else:\n                            return response\n", "path": "web3/providers/ipc.py"}], "after_files": [{"content": "import os\nimport socket\nimport sys\nimport threading\n\ntry:\n    from json import JSONDecodeError\nexcept ImportError:\n    JSONDecodeError = ValueError\n\nfrom web3.utils.threads import (\n    Timeout,\n)\n\nfrom .base import JSONBaseProvider\n\n\ndef get_ipc_socket(ipc_path, timeout=0.1):\n    if sys.platform == 'win32':\n        # On Windows named pipe is used. Simulate socket with it.\n        from web3.utils.windows import NamedPipe\n\n        return NamedPipe(ipc_path)\n    else:\n        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\n        sock.connect(ipc_path)\n        sock.settimeout(timeout)\n        return sock\n\n\nclass PersistantSocket(object):\n    sock = None\n\n    def __init__(self, ipc_path):\n        self.ipc_path = ipc_path\n\n    def __enter__(self):\n        if not self.ipc_path:\n            raise FileNotFoundError(\"cannot connect to IPC socket at path: %r\" % self.ipc_path)\n\n        if not self.sock:\n            self.sock = get_ipc_socket(self.ipc_path)\n        return self.sock\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        # only close the socket if there was an error\n        if exc_value is not None:\n            try:\n                self.sock.close()\n            except Exception:\n                pass\n            self.sock = None\n\n\ndef get_default_ipc_path(testnet=False):\n    if testnet:\n        testnet = \"testnet\"\n    else:\n        testnet = \"\"\n\n    if sys.platform == 'darwin':\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \"Library\",\n            \"Ethereum\",\n            testnet,\n            \"geth.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \"Library\",\n            \"Application Support\",\n            \"io.parity.ethereum\",\n            \"jsonrpc.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    elif sys.platform.startswith('linux'):\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \".ethereum\",\n            testnet,\n            \"geth.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.expanduser(os.path.join(\n            \"~\",\n            \".local\",\n            \"share\",\n            \"io.parity.ethereum\",\n            \"jsonrpc.ipc\"\n        ))\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    elif sys.platform == 'win32':\n        ipc_path = os.path.join(\n            \"\\\\\\\\\",\n            \".\",\n            \"pipe\",\n            \"geth.ipc\"\n        )\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n        ipc_path = os.path.join(\n            \"\\\\\\\\\",\n            \".\",\n            \"pipe\",\n            \"jsonrpc.ipc\"\n        )\n        if os.path.exists(ipc_path):\n            return ipc_path\n\n    else:\n        raise ValueError(\n            \"Unsupported platform '{0}'.  Only darwin/linux2/win32 are \"\n            \"supported.  You must specify the ipc_path\".format(sys.platform)\n        )\n\n\nclass IPCProvider(JSONBaseProvider):\n    _socket = None\n\n    def __init__(self, ipc_path=None, testnet=False, *args, **kwargs):\n        if ipc_path is None:\n            self.ipc_path = get_default_ipc_path(testnet)\n        else:\n            self.ipc_path = ipc_path\n\n        self._lock = threading.Lock()\n        self._socket = PersistantSocket(self.ipc_path)\n        super(IPCProvider, self).__init__(*args, **kwargs)\n\n    def make_request(self, method, params):\n        request = self.encode_rpc_request(method, params)\n\n        with self._lock, self._socket as sock:\n            sock.sendall(request)\n            raw_response = b\"\"\n            with Timeout(10) as timeout:\n                while True:\n                    try:\n                        raw_response += sock.recv(4096)\n                    except socket.timeout:\n                        timeout.sleep(0)\n                        continue\n                    if raw_response == b\"\":\n                        timeout.sleep(0)\n                    else:\n                        try:\n                            response = self.decode_rpc_response(raw_response)\n                        except JSONDecodeError:\n                            timeout.sleep(0)\n                            continue\n                        else:\n                            return response\n", "path": "web3/providers/ipc.py"}]}