============================================ test session starts =============================================
platform linux -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
rootdir: /tmp/pyhaversion
plugins: asyncio-0.21.0, aresponses-2.1.6
asyncio: mode=Mode.STRICT
collected 27 items
tests/test_container.py .......... [ 37%]
tests/test_haio.py ... [ 48%]
tests/test_local.py . [ 51%]
tests/test_pypi.py ..... [ 70%]
tests/test_supervisor.py F..F [ 85%]
tests/test_version.py .... [100%]
================================================== FAILURES ==================================================
____________________________________________ test_stable_version _____________________________________________
self = <pyhaversion.version.HaVersion object at 0x7f07f315e2d0>
async def get_version(
self,
*,
etag: str | None = None,
) -> tuple[AwesomeVersion, dict[str, Any]]:
"""
Get version update.
Returns a tupe with version, version_data.
"""
try:
> await self._handler.fetch(etag=etag)
pyhaversion/version.py:89:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = HaVersionSupervisor(source=<HaVersionSource.SUPERVISOR: 'supervisor'>, channel=<HaVersionChannel.STABLE: 'stable'>, board='ova', image='default', _etag=None)
kwargs = {'etag': None}
headers = {'Content-Type': 'application/json', 'If-None-Match': 'W/"test"', 'User-Agent': 'python/pyhaversion'}
etag = None
async def fetch(self, **kwargs):
"""Logic to fetch new version data."""
headers = DEFAULT_HEADERS
if (etag := kwargs.get("etag")) is not None:
headers[IF_NONE_MATCH] = etag
> request = await self.session.get(
url=URL.format(channel=self.channel),
headers=headers,
timeout=ClientTimeout(total=self.timeout),
)
pyhaversion/supervisor.py:47:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.client.ClientSession object at 0x7f07f315ed50>, method = 'GET'
str_or_url = 'https://version.home-assistant.io/HaVersionChannel.STABLE.json'
async def _request(
self,
method: str,
str_or_url: StrOrURL,
*,
params: Optional[Mapping[str, str]] = None,
data: Any = None,
json: Any = None,
cookies: Optional[LooseCookies] = None,
headers: Optional[LooseHeaders] = None,
skip_auto_headers: Optional[Iterable[str]] = None,
auth: Optional[BasicAuth] = None,
allow_redirects: bool = True,
max_redirects: int = 10,
compress: Optional[str] = None,
chunked: Optional[bool] = None,
expect100: bool = False,
raise_for_status: Optional[bool] = None,
read_until_eof: bool = True,
proxy: Optional[StrOrURL] = None,
proxy_auth: Optional[BasicAuth] = None,
timeout: Union[ClientTimeout, object] = sentinel,
verify_ssl: Optional[bool] = None,
fingerprint: Optional[bytes] = None,
ssl_context: Optional[SSLContext] = None,
ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
proxy_headers: Optional[LooseHeaders] = None,
trace_request_ctx: Optional[SimpleNamespace] = None,
read_bufsize: Optional[int] = None,
) -> ClientResponse:
# NOTE: timeout clamps existing connect and read timeouts. We cannot
# set the default to None because we need to detect if the user wants
# to use the existing timeouts by setting timeout to None.
if self.closed:
raise RuntimeError("Session is closed")
ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint)
if data is not None and json is not None:
raise ValueError(
"data and json parameters can not be used at the same time"
)
elif json is not None:
data = payload.JsonPayload(json, dumps=self._json_serialize)
if not isinstance(chunked, bool) and chunked is not None:
warnings.warn("Chunk size is deprecated #1615", DeprecationWarning)
redirects = 0
history = []
version = self._version
# Merge with default headers and transform to CIMultiDict
headers = self._prepare_headers(headers)
proxy_headers = self._prepare_headers(proxy_headers)
try:
url = self._build_url(str_or_url)
except ValueError as e:
raise InvalidURL(str_or_url) from e
skip_headers = set(self._skip_auto_headers)
if skip_auto_headers is not None:
for i in skip_auto_headers:
skip_headers.add(istr(i))
if proxy is not None:
try:
proxy = URL(proxy)
except ValueError as e:
raise InvalidURL(proxy) from e
if timeout is sentinel:
real_timeout: ClientTimeout = self._timeout
else:
if not isinstance(timeout, ClientTimeout):
real_timeout = ClientTimeout(total=timeout) # type: ignore[arg-type]
else:
real_timeout = timeout
# timeout is cumulative for all request operations
# (request, redirects, responses, data consuming)
tm = TimeoutHandle(self._loop, real_timeout.total)
handle = tm.start()
if read_bufsize is None:
read_bufsize = self._read_bufsize
traces = [
Trace(
self,
trace_config,
trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
)
for trace_config in self._trace_configs
]
for trace in traces:
await trace.send_request_start(method, url.update_query(params), headers)
timer = tm.timer()
try:
with timer:
while True:
url, auth_from_url = strip_auth_from_url(url)
if auth and auth_from_url:
raise ValueError(
"Cannot combine AUTH argument with "
"credentials encoded in URL"
)
if auth is None:
auth = auth_from_url
if auth is None:
auth = self._default_auth
# It would be confusing if we support explicit
# Authorization header with auth argument
if (
headers is not None
and auth is not None
and hdrs.AUTHORIZATION in headers
):
raise ValueError(
"Cannot combine AUTHORIZATION header "
"with AUTH argument or credentials "
"encoded in URL"
)
all_cookies = self._cookie_jar.filter_cookies(url)
if cookies is not None:
tmp_cookie_jar = CookieJar()
tmp_cookie_jar.update_cookies(cookies)
req_cookies = tmp_cookie_jar.filter_cookies(url)
if req_cookies:
all_cookies.load(req_cookies)
if proxy is not None:
proxy = URL(proxy)
elif self._trust_env:
with suppress(LookupError):
proxy, proxy_auth = get_env_proxy_for_url(url)
req = self._request_class(
method,
url,
params=params,
headers=headers,
skip_auto_headers=skip_headers,
data=data,
cookies=all_cookies,
auth=auth,
version=version,
compress=compress,
chunked=chunked,
expect100=expect100,
loop=self._loop,
response_class=self._response_class,
proxy=proxy,
proxy_auth=proxy_auth,
timer=timer,
session=self,
ssl=ssl,
proxy_headers=proxy_headers,
traces=traces,
)
# connection timeout
try:
async with ceil_timeout(real_timeout.connect):
assert self._connector is not None
conn = await self._connector.connect(
req, traces=traces, timeout=real_timeout
)
except asyncio.TimeoutError as exc:
raise ServerTimeoutError(
"Connection timeout " "to host {}".format(url)
) from exc
assert conn.transport is not None
assert conn.protocol is not None
conn.protocol.set_response_params(
timer=timer,
skip_payload=method.upper() == "HEAD",
read_until_eof=read_until_eof,
auto_decompress=self._auto_decompress,
read_timeout=real_timeout.sock_read,
read_bufsize=read_bufsize,
)
try:
try:
resp = await req.send(conn)
try:
> await resp.start(conn)
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/client.py:560:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ClientResponse(https://version.home-assistant.io/HaVersionChannel.STABLE.json) [None None]>
None
connection = Connection<ConnectionKey(host='version.home-assistant.io', port=443, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
async def start(self, connection: "Connection") -> "ClientResponse":
"""Start response processing."""
self._closed = False
self._protocol = connection.protocol
self._connection = connection
with self._timer:
while True:
# read response
try:
protocol = self._protocol
> message, payload = await protocol.read() # type: ignore[union-attr]
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/client_reqrep.py:899:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.client_proto.ResponseHandler object at 0x7f07f311fc40>
async def read(self) -> _T:
if not self._buffer and not self._eof:
assert not self._waiter
self._waiter = self._loop.create_future()
try:
> await self._waiter
E aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/streams.py:616: ServerDisconnectedError
The above exception was the direct cause of the following exception:
aresponses = <aresponses.main.ResponsesMockServer object at 0x7f07f315d590>
@pytest.mark.asyncio
async def test_stable_version(aresponses):
"""Test hassio stable."""
aresponses.add(
"version.home-assistant.io",
"/stable.json",
"get",
aresponses.Response(
text=fixture("supervisor/default", False), status=200, headers=HEADERS
),
)
async with aiohttp.ClientSession() as session:
haversion = HaVersion(session=session, source=HaVersionSource.SUPERVISOR)
> await haversion.get_version()
tests/test_supervisor.py:32:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyhaversion.version.HaVersion object at 0x7f07f315e2d0>
async def get_version(
self,
*,
etag: str | None = None,
) -> tuple[AwesomeVersion, dict[str, Any]]:
"""
Get version update.
Returns a tupe with version, version_data.
"""
try:
await self._handler.fetch(etag=etag)
except asyncio.TimeoutError as exception:
raise HaVersionFetchException(
f"Timeout of {self._handler.timeout} seconds was "
f"reached while fetching version for {self.source}"
) from exception
except (ClientError, gaierror) as exception:
> raise HaVersionFetchException(
f"Error fetching version information from {self.source} {exception}"
) from exception
E pyhaversion.exceptions.HaVersionFetchException: Error fetching version information from HaVersionSource.SUPERVISOR Server disconnected
pyhaversion/version.py:98: HaVersionFetchException
------------------------------------------- Captured stderr setup --------------------------------------------
DEBUG:asyncio:Using selector: EpollSelector
--------------------------------------------- Captured log setup ---------------------------------------------
DEBUG asyncio:selector_events.py:54 Using selector: EpollSelector
-------------------------------------------- Captured stderr call --------------------------------------------
ERROR:aiohttp.server:Unhandled runtime exception
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 600, in finish_response
prepare_meth = resp.prepare
^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 512, in start
resp, reset = await task
^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 458, in _handle_request
reset = await self.finish_response(request, resp, start_time)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 603, in finish_response
raise RuntimeError("Missing return " "statement on request handler")
RuntimeError: Missing return statement on request handler
--------------------------------------------- Captured log call ----------------------------------------------
ERROR aiohttp.server:web_protocol.py:403 Unhandled runtime exception
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 600, in finish_response
prepare_meth = resp.prepare
^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 512, in start
resp, reset = await task
^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 458, in _handle_request
reset = await self.finish_response(request, resp, start_time)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 603, in finish_response
raise RuntimeError("Missing return " "statement on request handler")
RuntimeError: Missing return statement on request handler
------------------------------------------ Captured stderr teardown ------------------------------------------
DEBUG:asyncio:Using selector: EpollSelector
------------------------------------------- Captured log teardown --------------------------------------------
DEBUG asyncio:selector_events.py:54 Using selector: EpollSelector
_________________________________________________ test_etag __________________________________________________
self = <pyhaversion.version.HaVersion object at 0x7f07f3115250>
async def get_version(
self,
*,
etag: str | None = None,
) -> tuple[AwesomeVersion, dict[str, Any]]:
"""
Get version update.
Returns a tupe with version, version_data.
"""
try:
> await self._handler.fetch(etag=etag)
pyhaversion/version.py:89:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = HaVersionSupervisor(source=<HaVersionSource.SUPERVISOR: 'supervisor'>, channel=<HaVersionChannel.STABLE: 'stable'>, board='ova', image='default', _etag=None)
kwargs = {'etag': None}
headers = {'Content-Type': 'application/json', 'If-None-Match': 'W/"test"', 'User-Agent': 'python/pyhaversion'}
etag = None
async def fetch(self, **kwargs):
"""Logic to fetch new version data."""
headers = DEFAULT_HEADERS
if (etag := kwargs.get("etag")) is not None:
headers[IF_NONE_MATCH] = etag
> request = await self.session.get(
url=URL.format(channel=self.channel),
headers=headers,
timeout=ClientTimeout(total=self.timeout),
)
pyhaversion/supervisor.py:47:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.client.ClientSession object at 0x7f07f3114fd0>, method = 'GET'
str_or_url = 'https://version.home-assistant.io/HaVersionChannel.STABLE.json'
async def _request(
self,
method: str,
str_or_url: StrOrURL,
*,
params: Optional[Mapping[str, str]] = None,
data: Any = None,
json: Any = None,
cookies: Optional[LooseCookies] = None,
headers: Optional[LooseHeaders] = None,
skip_auto_headers: Optional[Iterable[str]] = None,
auth: Optional[BasicAuth] = None,
allow_redirects: bool = True,
max_redirects: int = 10,
compress: Optional[str] = None,
chunked: Optional[bool] = None,
expect100: bool = False,
raise_for_status: Optional[bool] = None,
read_until_eof: bool = True,
proxy: Optional[StrOrURL] = None,
proxy_auth: Optional[BasicAuth] = None,
timeout: Union[ClientTimeout, object] = sentinel,
verify_ssl: Optional[bool] = None,
fingerprint: Optional[bytes] = None,
ssl_context: Optional[SSLContext] = None,
ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,
proxy_headers: Optional[LooseHeaders] = None,
trace_request_ctx: Optional[SimpleNamespace] = None,
read_bufsize: Optional[int] = None,
) -> ClientResponse:
# NOTE: timeout clamps existing connect and read timeouts. We cannot
# set the default to None because we need to detect if the user wants
# to use the existing timeouts by setting timeout to None.
if self.closed:
raise RuntimeError("Session is closed")
ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint)
if data is not None and json is not None:
raise ValueError(
"data and json parameters can not be used at the same time"
)
elif json is not None:
data = payload.JsonPayload(json, dumps=self._json_serialize)
if not isinstance(chunked, bool) and chunked is not None:
warnings.warn("Chunk size is deprecated #1615", DeprecationWarning)
redirects = 0
history = []
version = self._version
# Merge with default headers and transform to CIMultiDict
headers = self._prepare_headers(headers)
proxy_headers = self._prepare_headers(proxy_headers)
try:
url = self._build_url(str_or_url)
except ValueError as e:
raise InvalidURL(str_or_url) from e
skip_headers = set(self._skip_auto_headers)
if skip_auto_headers is not None:
for i in skip_auto_headers:
skip_headers.add(istr(i))
if proxy is not None:
try:
proxy = URL(proxy)
except ValueError as e:
raise InvalidURL(proxy) from e
if timeout is sentinel:
real_timeout: ClientTimeout = self._timeout
else:
if not isinstance(timeout, ClientTimeout):
real_timeout = ClientTimeout(total=timeout) # type: ignore[arg-type]
else:
real_timeout = timeout
# timeout is cumulative for all request operations
# (request, redirects, responses, data consuming)
tm = TimeoutHandle(self._loop, real_timeout.total)
handle = tm.start()
if read_bufsize is None:
read_bufsize = self._read_bufsize
traces = [
Trace(
self,
trace_config,
trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),
)
for trace_config in self._trace_configs
]
for trace in traces:
await trace.send_request_start(method, url.update_query(params), headers)
timer = tm.timer()
try:
with timer:
while True:
url, auth_from_url = strip_auth_from_url(url)
if auth and auth_from_url:
raise ValueError(
"Cannot combine AUTH argument with "
"credentials encoded in URL"
)
if auth is None:
auth = auth_from_url
if auth is None:
auth = self._default_auth
# It would be confusing if we support explicit
# Authorization header with auth argument
if (
headers is not None
and auth is not None
and hdrs.AUTHORIZATION in headers
):
raise ValueError(
"Cannot combine AUTHORIZATION header "
"with AUTH argument or credentials "
"encoded in URL"
)
all_cookies = self._cookie_jar.filter_cookies(url)
if cookies is not None:
tmp_cookie_jar = CookieJar()
tmp_cookie_jar.update_cookies(cookies)
req_cookies = tmp_cookie_jar.filter_cookies(url)
if req_cookies:
all_cookies.load(req_cookies)
if proxy is not None:
proxy = URL(proxy)
elif self._trust_env:
with suppress(LookupError):
proxy, proxy_auth = get_env_proxy_for_url(url)
req = self._request_class(
method,
url,
params=params,
headers=headers,
skip_auto_headers=skip_headers,
data=data,
cookies=all_cookies,
auth=auth,
version=version,
compress=compress,
chunked=chunked,
expect100=expect100,
loop=self._loop,
response_class=self._response_class,
proxy=proxy,
proxy_auth=proxy_auth,
timer=timer,
session=self,
ssl=ssl,
proxy_headers=proxy_headers,
traces=traces,
)
# connection timeout
try:
async with ceil_timeout(real_timeout.connect):
assert self._connector is not None
conn = await self._connector.connect(
req, traces=traces, timeout=real_timeout
)
except asyncio.TimeoutError as exc:
raise ServerTimeoutError(
"Connection timeout " "to host {}".format(url)
) from exc
assert conn.transport is not None
assert conn.protocol is not None
conn.protocol.set_response_params(
timer=timer,
skip_payload=method.upper() == "HEAD",
read_until_eof=read_until_eof,
auto_decompress=self._auto_decompress,
read_timeout=real_timeout.sock_read,
read_bufsize=read_bufsize,
)
try:
try:
resp = await req.send(conn)
try:
> await resp.start(conn)
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/client.py:560:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ClientResponse(https://version.home-assistant.io/HaVersionChannel.STABLE.json) [None None]>
None
connection = Connection<ConnectionKey(host='version.home-assistant.io', port=443, is_ssl=False, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
async def start(self, connection: "Connection") -> "ClientResponse":
"""Start response processing."""
self._closed = False
self._protocol = connection.protocol
self._connection = connection
with self._timer:
while True:
# read response
try:
protocol = self._protocol
> message, payload = await protocol.read() # type: ignore[union-attr]
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/client_reqrep.py:899:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aiohttp.client_proto.ResponseHandler object at 0x7f07f2ed1be0>
async def read(self) -> _T:
if not self._buffer and not self._eof:
assert not self._waiter
self._waiter = self._loop.create_future()
try:
> await self._waiter
E aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected
.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/streams.py:616: ServerDisconnectedError
The above exception was the direct cause of the following exception:
aresponses = <aresponses.main.ResponsesMockServer object at 0x7f07f30c1350>
@pytest.mark.asyncio
async def test_etag(aresponses):
"""Test hassio etag."""
aresponses.add(
"version.home-assistant.io",
"/stable.json",
"get",
aresponses.Response(
text=fixture("supervisor/default", False),
status=200,
headers={**HEADERS, "Etag": "test"},
),
)
aresponses.add(
"version.home-assistant.io",
"/stable.json",
"get",
aresponses.Response(status=304, headers=HEADERS),
)
async with aiohttp.ClientSession() as session:
haversion = HaVersion(session=session, source=HaVersionSource.SUPERVISOR)
> await haversion.get_version(etag=haversion.etag)
tests/test_supervisor.py:83:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pyhaversion.version.HaVersion object at 0x7f07f3115250>
async def get_version(
self,
*,
etag: str | None = None,
) -> tuple[AwesomeVersion, dict[str, Any]]:
"""
Get version update.
Returns a tupe with version, version_data.
"""
try:
await self._handler.fetch(etag=etag)
except asyncio.TimeoutError as exception:
raise HaVersionFetchException(
f"Timeout of {self._handler.timeout} seconds was "
f"reached while fetching version for {self.source}"
) from exception
except (ClientError, gaierror) as exception:
> raise HaVersionFetchException(
f"Error fetching version information from {self.source} {exception}"
) from exception
E pyhaversion.exceptions.HaVersionFetchException: Error fetching version information from HaVersionSource.SUPERVISOR Server disconnected
pyhaversion/version.py:98: HaVersionFetchException
------------------------------------------- Captured stderr setup --------------------------------------------
DEBUG:asyncio:Using selector: EpollSelector
--------------------------------------------- Captured log setup ---------------------------------------------
DEBUG asyncio:selector_events.py:54 Using selector: EpollSelector
-------------------------------------------- Captured stderr call --------------------------------------------
ERROR:aiohttp.server:Unhandled runtime exception
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 600, in finish_response
prepare_meth = resp.prepare
^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 512, in start
resp, reset = await task
^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 458, in _handle_request
reset = await self.finish_response(request, resp, start_time)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 603, in finish_response
raise RuntimeError("Missing return " "statement on request handler")
RuntimeError: Missing return statement on request handler
--------------------------------------------- Captured log call ----------------------------------------------
ERROR aiohttp.server:web_protocol.py:403 Unhandled runtime exception
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 600, in finish_response
prepare_meth = resp.prepare
^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 512, in start
resp, reset = await task
^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 458, in _handle_request
reset = await self.finish_response(request, resp, start_time)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/pyhaversion/.venv/lib/python3.11/site-packages/aiohttp-3.8.4-py3.11-linux-x86_64.egg/aiohttp/web_protocol.py", line 603, in finish_response
raise RuntimeError("Missing return " "statement on request handler")
RuntimeError: Missing return statement on request handler
------------------------------------------ Captured stderr teardown ------------------------------------------
DEBUG:asyncio:Using selector: EpollSelector
------------------------------------------- Captured log teardown --------------------------------------------
DEBUG asyncio:selector_events.py:54 Using selector: EpollSelector
========================================== short test summary info ===========================================
FAILED tests/test_supervisor.py::test_stable_version - pyhaversion.exceptions.HaVersionFetchException: Error fetching version information from HaVersionSource.S...
FAILED tests/test_supervisor.py::test_etag - pyhaversion.exceptions.HaVersionFetchException: Error fetching version information from HaVersionSource.S...
======================================== 2 failed, 25 passed in 0.16s ========================================