|
8 | 8 | import socket |
9 | 9 | import subprocess |
10 | 10 | from subprocess import PIPE, Popen |
11 | | -from typing import Any, Callable, Iterable, Sequence |
| 11 | +from typing import Any, Callable, Iterable, Mapping, Sequence |
12 | 12 | from warnings import warn |
13 | 13 |
|
14 | | -LOCAL_IPS: list = [] |
15 | | -PUBLIC_IPS: list = [] |
| 14 | +LOCAL_IPS: list[str] = [] |
| 15 | +PUBLIC_IPS: list[str] = [] |
16 | 16 |
|
17 | 17 | LOCALHOST: str = "" |
18 | 18 |
|
@@ -75,29 +75,34 @@ class NoIPAddresses(Exception): # noqa |
75 | 75 | pass |
76 | 76 |
|
77 | 77 |
|
78 | | -def _populate_from_list(addrs: Sequence[str] | None) -> None: |
| 78 | +def _populate_from_list(addrs: Sequence[str]) -> None: |
79 | 79 | """populate local and public IPs from flat list of all IPs""" |
| 80 | + _populate_from_dict({"all": addrs}) |
| 81 | + |
| 82 | + |
| 83 | +def _populate_from_dict(addrs: Mapping[str, Sequence[str]]) -> None: |
| 84 | + """populate local and public IPs from dict of {'en0': 'ip'}""" |
80 | 85 | if not addrs: |
81 | | - raise NoIPAddresses |
| 86 | + raise NoIPAddresses() |
82 | 87 |
|
83 | 88 | global LOCALHOST |
84 | 89 | public_ips = [] |
85 | 90 | local_ips = [] |
86 | 91 |
|
87 | | - for ip in addrs: |
88 | | - local_ips.append(ip) |
89 | | - if not ip.startswith("127."): |
90 | | - if not ip.startswith("169.254."): |
| 92 | + for iface, ip_list in addrs.items(): |
| 93 | + for ip in ip_list: |
| 94 | + local_ips.append(ip) |
| 95 | + if not LOCALHOST and (iface.startswith("lo") or ip.startswith("127.")): |
| 96 | + LOCALHOST = ip |
| 97 | + if not iface.startswith("lo") and not ip.startswith(("127.", "169.254.")): |
91 | 98 | # don't include link-local address in public_ips |
92 | 99 | public_ips.append(ip) |
93 | | - elif not LOCALHOST: |
94 | | - LOCALHOST = ip |
95 | 100 |
|
96 | 101 | if not LOCALHOST or LOCALHOST == "127.0.0.1": |
97 | 102 | LOCALHOST = "127.0.0.1" |
98 | 103 | local_ips.insert(0, LOCALHOST) |
99 | 104 |
|
100 | | - local_ips.extend(["0.0.0.0", ""]) # noqa |
| 105 | + local_ips.extend(["0.0.0.0", ""]) # noqa: S104 |
101 | 106 |
|
102 | 107 | LOCAL_IPS[:] = _uniq_stable(local_ips) |
103 | 108 | PUBLIC_IPS[:] = _uniq_stable(public_ips) |
@@ -157,65 +162,38 @@ def _load_ips_psutil() -> None: |
157 | 162 | """load ip addresses with netifaces""" |
158 | 163 | import psutil |
159 | 164 |
|
160 | | - global LOCALHOST |
161 | | - local_ips = [] |
162 | | - public_ips = [] |
| 165 | + addr_dict: dict[str, list[str]] = {} |
163 | 166 |
|
164 | 167 | # dict of iface_name: address_list, eg |
165 | 168 | # {"lo": [snicaddr(family=<AddressFamily.AF_INET>, address="127.0.0.1", |
166 | 169 | # ...), snicaddr(family=<AddressFamily.AF_INET6>, ...)]} |
167 | 170 | for iface, ifaddresses in psutil.net_if_addrs().items(): |
168 | | - for address_data in ifaddresses: |
169 | | - if address_data.family == socket.AF_INET: |
170 | | - addr = address_data.address |
171 | | - if not (iface.startswith("lo") or addr.startswith("127.")): |
172 | | - public_ips.append(addr) |
173 | | - elif addr.startswith("169.254."): |
174 | | - # don't include link-local address in public_ips |
175 | | - pass |
176 | | - elif not LOCALHOST: |
177 | | - LOCALHOST = addr |
178 | | - local_ips.append(addr) |
179 | | - if not LOCALHOST: |
180 | | - # we never found a loopback interface (can this ever happen?), assume common default |
181 | | - LOCALHOST = "127.0.0.1" |
182 | | - local_ips.insert(0, LOCALHOST) |
183 | | - local_ips.extend(["0.0.0.0", ""]) # noqa |
184 | | - LOCAL_IPS[:] = _uniq_stable(local_ips) |
185 | | - PUBLIC_IPS[:] = _uniq_stable(public_ips) |
| 171 | + addr_dict[iface] = [ |
| 172 | + address_data.address |
| 173 | + for address_data in ifaddresses |
| 174 | + if address_data.family == socket.AF_INET |
| 175 | + ] |
| 176 | + |
| 177 | + _populate_from_dict(addr_dict) |
186 | 178 |
|
187 | 179 |
|
188 | 180 | def _load_ips_netifaces() -> None: |
189 | 181 | """load ip addresses with netifaces""" |
190 | 182 | import netifaces # type: ignore[import-not-found] |
191 | 183 |
|
192 | | - global LOCALHOST |
193 | | - local_ips = [] |
194 | | - public_ips = [] |
| 184 | + addr_dict: dict[str, list[str]] = {} |
195 | 185 |
|
196 | 186 | # list of iface names, 'lo0', 'eth0', etc. |
197 | 187 | for iface in netifaces.interfaces(): |
198 | 188 | # list of ipv4 addrinfo dicts |
| 189 | + addr_dict[iface] = [] |
| 190 | + |
199 | 191 | ipv4s = netifaces.ifaddresses(iface).get(netifaces.AF_INET, []) |
200 | 192 | for entry in ipv4s: |
201 | 193 | addr = entry.get("addr") |
202 | | - if not addr: |
203 | | - continue |
204 | | - if not (iface.startswith("lo") or addr.startswith("127.")): |
205 | | - public_ips.append(addr) |
206 | | - elif addr.startswith("169.254."): |
207 | | - # don't include link-local address in public_ips |
208 | | - pass |
209 | | - elif not LOCALHOST: |
210 | | - LOCALHOST = addr |
211 | | - local_ips.append(addr) |
212 | | - if not LOCALHOST: |
213 | | - # we never found a loopback interface (can this ever happen?), assume common default |
214 | | - LOCALHOST = "127.0.0.1" |
215 | | - local_ips.insert(0, LOCALHOST) |
216 | | - local_ips.extend(["0.0.0.0", ""]) # noqa |
217 | | - LOCAL_IPS[:] = _uniq_stable(local_ips) |
218 | | - PUBLIC_IPS[:] = _uniq_stable(public_ips) |
| 194 | + if addr: |
| 195 | + addr_dict[iface].append(addr) |
| 196 | + _populate_from_dict(addr_dict) |
219 | 197 |
|
220 | 198 |
|
221 | 199 | def _load_ips_gethostbyname() -> None: |
|
0 commit comments