Check if requirement is typed in strict_typing IQS validation (#133415)
* Check if requirement is typed in strict_typing IQS validation * Apply suggestions from code review * Apply suggestions from code review * Return a list * Adjust * Improvepull/133421/head
parent
637614299c
commit
e61142c2c2
|
@ -95,4 +95,7 @@ rules:
|
|||
comment: |
|
||||
the fritzconnection lib is not async and relies on requests
|
||||
changing this might need a bit more efforts to be spent
|
||||
strict-typing: done
|
||||
strict-typing:
|
||||
status: todo
|
||||
comment: |
|
||||
Requirements 'fritzconnection==1.14.0' and 'xmltodict==0.13.0' appear untyped
|
||||
|
|
|
@ -94,4 +94,7 @@ rules:
|
|||
status: exempt
|
||||
comment: |
|
||||
This integration does not use web sessions.
|
||||
strict-typing: done
|
||||
strict-typing:
|
||||
status: todo
|
||||
comment: |
|
||||
Requirement 'aioimaplib==1.1.0' appears untyped
|
||||
|
|
|
@ -93,4 +93,7 @@ rules:
|
|||
# Platinum
|
||||
async-dependency: todo
|
||||
inject-websession: todo
|
||||
strict-typing: done
|
||||
strict-typing:
|
||||
status: todo
|
||||
comment: |
|
||||
Requirement 'Mastodon.py==1.8.1' appears untyped
|
||||
|
|
|
@ -125,4 +125,7 @@ rules:
|
|||
status: exempt
|
||||
comment: |
|
||||
This integration does not use web sessions.
|
||||
strict-typing: done
|
||||
strict-typing:
|
||||
status: todo
|
||||
comment: |
|
||||
Requirement 'paho-mqtt==1.6.1' appears untyped
|
||||
|
|
|
@ -86,4 +86,7 @@ rules:
|
|||
# Platinum
|
||||
async-dependency: done
|
||||
inject-websession: done
|
||||
strict-typing: done
|
||||
strict-typing:
|
||||
status: todo
|
||||
comment: |
|
||||
Requirement 'stookwijzer==1.5.1' appears untyped
|
||||
|
|
|
@ -4,6 +4,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/s
|
|||
"""
|
||||
|
||||
from functools import lru_cache
|
||||
from importlib import metadata
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
@ -24,6 +25,29 @@ def _strict_typing_components(strict_typing_file: Path) -> set[str]:
|
|||
)
|
||||
|
||||
|
||||
def _check_requirements_are_typed(integration: Integration) -> list[str]:
|
||||
"""Check if all requirements are typed."""
|
||||
invalid_requirements = []
|
||||
for requirement in integration.requirements:
|
||||
requirement_name, requirement_version = requirement.split("==")
|
||||
# Remove any extras
|
||||
requirement_name = requirement_name.split("[")[0]
|
||||
try:
|
||||
distribution = metadata.distribution(requirement_name)
|
||||
except metadata.PackageNotFoundError:
|
||||
# Package not installed locally
|
||||
continue
|
||||
if distribution.version != requirement_version:
|
||||
# Version out of date locally
|
||||
continue
|
||||
|
||||
if not any(file for file in distribution.files if file.name == "py.typed"):
|
||||
# no py.typed file
|
||||
invalid_requirements.append(requirement)
|
||||
|
||||
return invalid_requirements
|
||||
|
||||
|
||||
def validate(
|
||||
config: Config, integration: Integration, *, rules_done: set[str]
|
||||
) -> list[str] | None:
|
||||
|
@ -35,4 +59,9 @@ def validate(
|
|||
"Integration does not have strict typing enabled "
|
||||
"(is missing from .strict-typing)"
|
||||
]
|
||||
if untyped_requirements := _check_requirements_are_typed(integration):
|
||||
return [
|
||||
f"Requirements {untyped_requirements} do not conform PEP 561 (https://peps.python.org/pep-0561/)",
|
||||
"They should be typed and have a 'py.typed' file",
|
||||
]
|
||||
return None
|
||||
|
|
Loading…
Reference in New Issue