-
-
Notifications
You must be signed in to change notification settings - Fork 28.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add TypeVar defaults for DataUpdateCoordinator and EntityComponent #95026
Conversation
Hey there @bdraco, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested on production, no performance or adverse side effects observed.
Thanks @cdce8p |
@@ -30,12 +31,14 @@ | |||
REQUEST_REFRESH_DEFAULT_COOLDOWN = 10 | |||
REQUEST_REFRESH_DEFAULT_IMMEDIATE = True | |||
|
|||
_T = TypeVar("_T") | |||
_DataT = TypeVar("_DataT", default=dict[str, Any]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this type the coordinator data as dict[str, Any]
even if the implementing integration hasn't added type annotations? That would be misleading and incorrect I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this type the coordinator data as
dict[str, Any]
even if the implementing integration hasn't added type annotations? That would be misleading and incorrect I think.
Yes, but that's by design. A lot of times, CoordinatorEntity
is used without any generic type. That causes mypy to skip all subsequent checks for self.coordinator.data
as the type is assumed to be Any
. In reality most integrations start out with dict[str, Any]
. However, once the integration grows, the data type is often changed to a custom one like TypedDict or DataClass. Even then, the set default
will be helpful. Once mypy fully supports PEP 696, it will warn that for example data
doesn't have a specific attribute. There will also be a message that the type for _async_update_data
doesn't match dict[str, Any]
. Both of these can be used as hints to update the generic type for CoordinatorEntity
/ DataUpdateCoordinator
.
Some examples
Airthings
still uses a dict[str, Any]
.
class AirthingsHeaterEnergySensor(CoordinatorEntity, SensorEntity): |
core/homeassistant/components/airthings/sensor.py
Lines 163 to 166 in 8987e02
@property | |
def native_value(self) -> StateType: | |
"""Return the value reported by the sensor.""" | |
return self.coordinator.data[self._id].sensors[self.entity_description.key] |
I mentioned the PR for notion
earlier already #91883. Say we remove all generic arguments for CoordinatorEntity
and DataUpdateCoordinator
, with a future mypy version we would get these errors:
homeassistant/components/notion/__init__.py:290: error: "dict[str, Any]" has no attribute "bridges" [attr-defined]
homeassistant/components/notion/__init__.py:291: error: "dict[str, Any]" has no attribute "sensors" [attr-defined]
homeassistant/components/notion/__init__.py:314: error: "dict[str, Any]" has no attribute "listeners" [attr-defined]
homeassistant/components/notion/__init__.py:320: error: Returning Any from function declared to return "Listener" [no-any-return]
homeassistant/components/notion/__init__.py:320: error: "dict[str, Any]" has no attribute "listeners" [attr-defined]
homeassistant/components/notion/__init__.py:328: error: "dict[str, Any]" has no attribute "sensors" [attr-defined]
homeassistant/components/notion/__init__.py:335: error: "dict[str, Any]" has no attribute "bridges" [attr-defined]
homeassistant/components/notion/__init__.py:343: error: "dict[str, Any]" has no attribute "bridges" [attr-defined]
homeassistant/components/notion/__init__.py:356: error: "dict[str, Any]" has no attribute "listeners" [attr-defined]
homeassistant/components/notion/sensor.py:70: error: "dict[str, Any]" has no attribute "user_preferences" [attr-defined]
homeassistant/components/notion/sensor.py:72: error: "dict[str, Any]" has no attribute "user_preferences" [attr-defined]
homeassistant/components/notion/diagnostics.py:43: error: "dict[str, Any]" has no attribute "asdict" [attr-defined]
Whereas without we only get one and wouldn't even know that the generic type is wrong
homeassistant/components/notion/__init__.py:320: error: Returning Any from function declared to return "Listener" [no-any-return]
--
Over the last few weeks, I've already added generic arguments to integrations which use (strict) type checking and have a custom data / DataUpdateCoordinator type. At least the issues I could find are fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't get any warnings of incorrect type with the current mypy version the default may just silently be wrong and misleading. I don't think we should add it until we get warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't get any warnings of incorrect type with the current mypy version the default may just silently be wrong and misleading. I don't think we should add it until we get warnings.
I'm working on the mypy support, hopefully the warning will be there with the release next month 🤞🏻
In the meantime, it's still an improvement as I suspect a lot / most use VS Code and Pylance which will already display the errors (if they have enabled the type checking mode).
I'm not planning to add any more defaults until then, just for these once I think the benefits outweigh the small risk of it becoming outdated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree that the benefits outweigh the problems and think we should remove this for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guess we have different opinions there. Anyway you call the shots. Opened #95101
…onent (home-assistant#95026)" This reverts commit 90f5b1c.
Proposed change
Followup to #94987
For mypy
1.4.0
I've started adding initial support forTypeVar
defaults PEP 696. It's still in the early phases, however a few improvements are already possible. Basically those in this PR, nothing more yet.For the moment, adding the TypeVar defaults for
DataUpdateCoordinator
andEntityComponent
will only improve code completions in VS Code. E.g. where previouslyself.coordinator.data
would only suggestAny / Unknown
, it now defaults to the TypeVar defaultdict[str, Any]
.Once the support in mypy is better, it will also help catch typing issues. I've been testing an experimental mypy build for some time now and already fixed a lot of them. E.g. #91883
Type of change
Additional information
Checklist
black --fast homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
..coveragerc
.To help with the load of incoming pull requests: