Skip to content
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

Annotate more async functions correctly #31802

Merged
merged 1 commit into from
Feb 14, 2020
Merged

Conversation

balloob
Copy link
Member

@balloob balloob commented Feb 13, 2020

Breaking change

Proposed change

In my previous PRs I looked for functions where the name started with async_ but were not async and had no @callback decorator. Now I expanded the search for functions starting with _async_

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Example entry for configuration.yaml:

# Example configuration.yaml

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • Untested files have been added to .coveragerc.

The integration reached or maintains the following Integration Quality Scale:

  • No score or internal
  • 🥈 Silver
  • 🥇 Gold
  • 🏆 Platinum

@probot-home-assistant
Copy link

Hey there @OttoWinter, mind taking a look at this pull request as its been labeled with a integration (esphome) you are listed as a codeowner for? Thanks!

@probot-home-assistant
Copy link

Hey there @Anonym-tsk, mind taking a look at this pull request as its been labeled with a integration (starline) you are listed as a codeowner for? Thanks!

@probot-home-assistant
Copy link

Hey there @robbiet480, mind taking a look at this pull request as its been labeled with a integration (upnp) you are listed as a codeowner for? Thanks!

@probot-home-assistant
Copy link

Hey there @OnFreund, mind taking a look at this pull request as its been labeled with a integration (coolmaster) you are listed as a codeowner for? Thanks!

@probot-home-assistant
Copy link

Hey there @MartinHjelmare, mind taking a look at this pull request as its been labeled with a integration (mysensors) you are listed as a codeowner for? Thanks!

@probot-home-assistant
Copy link

Hey there @Jc2k, mind taking a look at this pull request as its been labeled with a integration (homekit_controller) you are listed as a codeowner for? Thanks!

@@ -150,11 +151,13 @@ def _turn_on_rgb_and_w(self, hex_template, **kwargs):
self._values[value_type] = STATE_OFF
self.async_schedule_update_ha_state()

@callback
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods are just called internally and don't need to be decorated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that @callback is not just a decorator to instruct Home Assistant on how to execute the function, it's also an indicator fo rthe reader that this is a function that should be called from within the event loop.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I wrote in the other PR. We will never be able to name functions or decorate things to 100% so we can't trust this. Sure it might help where it does match but since we can't trust the existence or absence of this decorator to be the truth about where a function should be run, I don't think we should spend time on trying to add this everywhere.

Copy link
Member

@MartinHjelmare MartinHjelmare Feb 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do want to use a system like this for the purpose you describe and be able to trust it, we would have to introduce another decorator, called eg sync and decorate all sync functions with it. Then we could check if a function is a coroutine, a callback that should run in the event loop or a sync function that should not run in the event loop. We would know that an undecorated function that isn't a coroutine would be unmarked and we could exclude that function from the trust chain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this is my third PR doing this actually, and I did find some issues where things were accidentally being called in the executor instead of a callback. I think that sticking to prefixing function names with async_ and adding either async def or @callback will help us catch these things. It's not 100%, but it's better than nothing. Async stuff running outside of the event loop can cause a whole bunch of issues, as async functions are not thread safe (because they are run after one another).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not 100% convinced of a sync decorator, as this is about functions that have the async_ prefix. For sync functions there is no disctinction. Right now it's no decorator -> it's sync.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that's the problem. Without a decorator we can't tell if someone has looked at the function and decided it's not async or just haven't looked at it.

Copy link
Member

@MartinHjelmare MartinHjelmare Feb 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would need two new decorators, probably. One sync for functions that should not run in the event loop, and one safe for functions that can both run in the event loop or in another thread.

So in total it's four different type of functions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could consider that. I don't think that's a priority.

I've found real bugs making sure all functions starting with async_ are decorated or async. And so we should continue doing so.

@codecov
Copy link

codecov bot commented Feb 13, 2020

Codecov Report

Merging #31802 into dev will decrease coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev   #31802      +/-   ##
==========================================
- Coverage   94.68%   94.67%   -0.01%     
==========================================
  Files         763      763              
  Lines       55128    55151      +23     
==========================================
+ Hits        52197    52214      +17     
- Misses       2931     2937       +6
Impacted Files Coverage Δ
homeassistant/helpers/entity_component.py 96.82% <100%> (+0.02%) ⬆️
...stant/components/homekit_controller/config_flow.py 100% <100%> (ø) ⬆️
homeassistant/components/coolmaster/config_flow.py 100% <100%> (ø) ⬆️
homeassistant/components/esphome/config_flow.py 100% <100%> (ø) ⬆️
homeassistant/helpers/restore_state.py 98.44% <100%> (+0.01%) ⬆️
homeassistant/components/template/cover.py 96.34% <0%> (-1.37%) ⬇️
homeassistant/helpers/config_validation.py 95.66% <0%> (-0.4%) ⬇️
homeassistant/helpers/entity.py 97.27% <0%> (-0.33%) ⬇️
homeassistant/components/ps4/media_player.py 89.76% <0%> (-0.16%) ⬇️
homeassistant/components/simplisafe/const.py 100% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3e23a3a...8f4b9e5. Read the comment docs.

@balloob balloob merged commit e019280 into dev Feb 14, 2020
Dev automation moved this from Needs review to Done Feb 14, 2020
@delete-merged-branch delete-merged-branch bot deleted the annotate-more-async-func branch February 14, 2020 18:00
@lock lock bot locked and limited conversation to collaborators Feb 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Dev
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

6 participants