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

Add and fix some Huawei LTE type hints #41196

Merged
merged 1 commit into from
Oct 5, 2020
Merged

Add and fix some Huawei LTE type hints #41196

merged 1 commit into from
Oct 5, 2020

Conversation

scop
Copy link
Member

@scop scop commented Oct 4, 2020

Proposed change

Adds a bunch of trivialish type hints to huawei_lte, to get the easily reviewable ones out of the way of slightly bigger related changes.

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

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

To help with the load of incoming pull requests:

@probot-home-assistant
Copy link

Hey there @fphammerle, mind taking a look at this pull request as its been labeled with an integration (huawei_lte) you are listed as a codeowner for? Thanks!
(message by CodeOwnersMention)

Copy link
Contributor

@fphammerle fphammerle left a comment

Choose a reason for hiding this comment

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

Thanks! Type hints look correct to me

I just added cosmetic suggestions (more specific hints).

@@ -275,7 +275,7 @@ def logout(self) -> None:
except Exception: # pylint: disable=broad-except
_LOGGER.warning("Logout error", exc_info=True)

def cleanup(self, *_) -> None:
def cleanup(self, *_: Any) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

just cosmetics but maybe:

Suggested change
def cleanup(self, *_: Any) -> None:
def cleanup(self, *_: Tuple) -> None:

Copy link
Member Author

@scop scop Oct 5, 2020

Choose a reason for hiding this comment

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

self.cleanup gets passed to HomeAssistant.async_add_executor_job and EventBus.async_listen_once, and the relevant parameter in the first is Callable[..., T], and in the latter it's just Callable. As we are not affecting what actually gets passed to this function as parameters, I don't think it would be quite appropriate to make the type hints more specific here -- that would be manifesting internal implementation detail of those functions more than they currently expose in their type hints themselves.

(It would be good to make those type hints more specific if possible, but that's something for a different PR.)

@@ -81,7 +82,7 @@ def async_add_new_entities(hass, router_url, async_add_entities, tracked):
_LOGGER.debug("%s[%s][%s] not in data", KEY_WLAN_HOST_LIST, "Hosts", "Host")
return

new_entities = []
new_entities: List[Entity] = []
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe more specific?

Suggested change
new_entities: List[Entity] = []
new_entities: List[HuaweiLteScannerEntity] = []

Copy link
Contributor

Choose a reason for hiding this comment

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

should still be compatible with async_add_entities as Entity inherits from HuaweiLteScannerEntity, right?

same question for HuaweiLteSensor / async_add_entities below

Copy link
Member Author

@scop scop Oct 5, 2020

Choose a reason for hiding this comment

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

List is not covariant, so this would cause mypy to barf:

homeassistant/components/huawei_lte/device_tracker.py:103: error: Argument 1 has incompatible type "List[HuaweiLteScannerEntity]"; expected "List[Entity]"
homeassistant/components/huawei_lte/device_tracker.py:103: note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
homeassistant/components/huawei_lte/device_tracker.py:103: note: Consider using "Sequence" instead, which is covariant

(Aside, our function parameter type hints should in general be changed towards abstract classes ("interfaces") as appropriate instead of using concrete types like List (concrete return types are fine). That would be the right thing to do in general, and would improve things in this case as a side effect.)

"""Turn switch on."""
self._turn(state=True)

def turn_off(self, **kwargs):
def turn_off(self, **kwargs: Any) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe:

Suggested change
def turn_off(self, **kwargs: Any) -> None:
def turn_off(self, **kwargs: Dict[str, Any]) -> None:

same for turn_on

Copy link
Member Author

@scop scop Oct 5, 2020

Choose a reason for hiding this comment

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

I don't think that's necessary or idiomatic, and I suppose it would be actually wrong. Keyword arguments always come as str keyed dicts, and although I'm unable to locate a doc reference to back it up, I think **kwargs: Any along with some type checker magic is a shorthand notation for that.

Anyway, turn_on and turn_off are explicitly hinted with **kwargs: Any in ToggleEntity where they originate from, and like in the cleanup case above, we're not affecting in any way what actually gets passed to them as parameters nor using them, so copying the superclass hints is the right thing to do.

Copy link
Member Author

Choose a reason for hiding this comment

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

Found the missing doc reference: https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values

def foo(*args: str, **kwds: int): ...
In the body of function foo, the type of variable args is deduced as Tuple[str, ...] and the type of variable kwds is Dict[str, int].

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for all the explanations and docs reference!

@balloob balloob merged commit 56f0a68 into home-assistant:dev Oct 5, 2020
@scop scop deleted the huawei-lte-typecheck-some branch October 5, 2020 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants