Fix special case in pylint type hint plugin (#118454)

* Fix special case in pylint type hint plugin

* Simplify

* Simplify

* Simplify

* Apply

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>

---------

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
This commit is contained in:
epenet 2024-05-30 10:41:32 +02:00 committed by GitHub
parent c6e0e93680
commit 06251d403a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 9 additions and 2 deletions

View file

@ -69,7 +69,7 @@ class ClassTypeHintMatch:
matches: list[TypeHintMatch] matches: list[TypeHintMatch]
_INNER_MATCH = r"((?:[\w\| ]+)|(?:\.{3})|(?:\w+\[.+\]))" _INNER_MATCH = r"((?:[\w\| ]+)|(?:\.{3})|(?:\w+\[.+\])|(?:\[\]))"
_TYPE_HINT_MATCHERS: dict[str, re.Pattern[str]] = { _TYPE_HINT_MATCHERS: dict[str, re.Pattern[str]] = {
# a_or_b matches items such as "DiscoveryInfoType | None" # a_or_b matches items such as "DiscoveryInfoType | None"
# or "dict | list | None" # or "dict | list | None"
@ -2914,6 +2914,10 @@ def _is_valid_type(
if expected_type == "...": if expected_type == "...":
return isinstance(node, nodes.Const) and node.value == Ellipsis return isinstance(node, nodes.Const) and node.value == Ellipsis
# Special case for an empty list, such as Callable[[], TestServer]
if expected_type == "[]":
return isinstance(node, nodes.List) and not node.elts
# Special case for `xxx | yyy` # Special case for `xxx | yyy`
if match := _TYPE_HINT_MATCHERS["a_or_b"].match(expected_type): if match := _TYPE_HINT_MATCHERS["a_or_b"].match(expected_type):
return ( return (

View file

@ -54,6 +54,7 @@ def test_regex_get_module_platform(
("list[dict[str, str]]", 1, ("list", "dict[str, str]")), ("list[dict[str, str]]", 1, ("list", "dict[str, str]")),
("list[dict[str, Any]]", 1, ("list", "dict[str, Any]")), ("list[dict[str, Any]]", 1, ("list", "dict[str, Any]")),
("tuple[bytes | None, str | None]", 2, ("tuple", "bytes | None", "str | None")), ("tuple[bytes | None, str | None]", 2, ("tuple", "bytes | None", "str | None")),
("Callable[[], TestServer]", 2, ("Callable", "[]", "TestServer")),
], ],
) )
def test_regex_x_of_y_i( def test_regex_x_of_y_i(
@ -1130,12 +1131,14 @@ def test_notify_get_service(
def test_pytest_function( def test_pytest_function(
linter: UnittestLinter, type_hint_checker: BaseChecker linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None: ) -> None:
"""Ensure valid hints are accepted for async_get_service.""" """Ensure valid hints are accepted for a test function."""
func_node = astroid.extract_node( func_node = astroid.extract_node(
""" """
async def test_sample( #@ async def test_sample( #@
hass: HomeAssistant, hass: HomeAssistant,
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
aiohttp_server: Callable[[], TestServer],
unused_tcp_port_factory: Callable[[], int],
) -> None: ) -> None:
pass pass
""", """,