Avoid converting discovery_info dataclasses to dict that will be thrown away in config flows (#75451)

* Avoid converting BluetoothServiceInfo to a dict for default discovery

Fixes
```
2022-07-19 09:46:48.303 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/homeassistant/helpers/discovery_flow.py", line 74, in _async_process_pending_flows
    await gather_with_concurrency(
  File "/Users/bdraco/home-assistant/homeassistant/util/async_.py", line 201, in gather_with_concurrency
    return await gather(
  File "/Users/bdraco/home-assistant/homeassistant/util/async_.py", line 199, in sem_task
    return await task
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 222, in async_init
    flow, result = await task
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 249, in _async_init
    result = await self._async_handle_step(flow, flow.init_step, data, init_done)
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 359, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/Users/bdraco/home-assistant/homeassistant/config_entries.py", line 1484, in async_step_bluetooth
    return await self.async_step_discovery(dataclasses.asdict(discovery_info))
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1239, in asdict
    return _asdict_inner(obj, dict_factory)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1246, in _asdict_inner
    value = _asdict_inner(getattr(obj, f.name), dict_factory)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1280, in _asdict_inner
    return copy.deepcopy(obj)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: Cannot pickle Objective-C objects
```

* Avoid converting BluetoothServiceInfo to a dict for default discovery

Fixes
```
2022-07-19 09:46:48.303 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/homeassistant/helpers/discovery_flow.py", line 74, in _async_process_pending_flows
    await gather_with_concurrency(
  File "/Users/bdraco/home-assistant/homeassistant/util/async_.py", line 201, in gather_with_concurrency
    return await gather(
  File "/Users/bdraco/home-assistant/homeassistant/util/async_.py", line 199, in sem_task
    return await task
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 222, in async_init
    flow, result = await task
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 249, in _async_init
    result = await self._async_handle_step(flow, flow.init_step, data, init_done)
  File "/Users/bdraco/home-assistant/homeassistant/data_entry_flow.py", line 359, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/Users/bdraco/home-assistant/homeassistant/config_entries.py", line 1484, in async_step_bluetooth
    return await self.async_step_discovery(dataclasses.asdict(discovery_info))
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1239, in asdict
    return _asdict_inner(obj, dict_factory)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1246, in _asdict_inner
    value = _asdict_inner(getattr(obj, f.name), dict_factory)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/dataclasses.py", line 1280, in _asdict_inner
    return copy.deepcopy(obj)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/opt/homebrew/Cellar/python@3.10/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/copy.py", line 161, in deepcopy
    rv = reductor(4)
TypeError: Cannot pickle Objective-C objects
```
This commit is contained in:
J. Nick Koston 2022-07-19 11:50:30 -05:00 committed by GitHub
parent 5ae5ae5392
commit 32311f240b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,7 +5,6 @@ import asyncio
from collections import ChainMap
from collections.abc import Callable, Coroutine, Iterable, Mapping
from contextvars import ContextVar
import dataclasses
from enum import Enum
import functools
import logging
@ -1446,13 +1445,19 @@ class ConfigFlow(data_entry_flow.FlowHandler):
if self._async_in_progress(include_uninitialized=True):
raise data_entry_flow.AbortFlow("already_in_progress")
async def async_step_discovery(
self, discovery_info: DiscoveryInfoType
async def _async_step_discovery_without_unique_id(
self,
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by discovery."""
await self._async_handle_discovery_without_unique_id()
return await self.async_step_user()
async def async_step_discovery(
self, discovery_info: DiscoveryInfoType
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by discovery."""
return await self._async_step_discovery_without_unique_id()
@callback
def async_abort(
self,
@ -1481,55 +1486,55 @@ class ConfigFlow(data_entry_flow.FlowHandler):
self, discovery_info: BluetoothServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by Bluetooth discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_dhcp(
self, discovery_info: DhcpServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by DHCP discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_hassio(
self, discovery_info: HassioServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by HASS IO discovery."""
return await self.async_step_discovery(discovery_info.config)
return await self._async_step_discovery_without_unique_id()
async def async_step_integration_discovery(
self, discovery_info: DiscoveryInfoType
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by integration specific discovery."""
return await self.async_step_discovery(discovery_info)
return await self._async_step_discovery_without_unique_id()
async def async_step_homekit(
self, discovery_info: ZeroconfServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by Homekit discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_mqtt(
self, discovery_info: MqttServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by MQTT discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_ssdp(
self, discovery_info: SsdpServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by SSDP discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_usb(
self, discovery_info: UsbServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by USB discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle a flow initialized by Zeroconf discovery."""
return await self.async_step_discovery(dataclasses.asdict(discovery_info))
return await self._async_step_discovery_without_unique_id()
@callback
def async_create_entry(