Skip to content

Type hints for ´sized´ matchers do not allow for instances of subclasses of ´Sized´. #178

@david-anders

Description

@david-anders

I didnt find this issue mentioned anywhere, so I'm sorry if i missed it, or if i'm doing something wrong.

When creating tests for collection objects I'm getting plenty of type errors, from mypy as well as the PyCharm builtin type checker.

Example:
The following:

assert_that([], is_(empty()))

results in:

Unexpected type(s): (list, Matcher[Sized]) Possible types: (bool, str) (list, Matcher[list])

It seems to me to be because the type declaration of the empty matcher is too strict/"working in the wrong direction".
This can be solved by using a TypeVar instead of the static Matcher[Sized] type declaration (see the ´empty2´ definition in the example below)

Code snippet for clarification:

from typing import TypeVar, Sized, List, Any

from hamcrest.core.assert_that import assert_that
from hamcrest.core.core.is_ import is_
from hamcrest.core.matcher import Matcher
from hamcrest.library.collection import empty


SizedT = TypeVar("SizedT", bound=Sized)


def empty2() -> Matcher[SizedT]:
    """
    wraps the ´hamcrest.empty´ Matcher with type hints that support instances of subclasses of ´typing.Sized´.
    """
    return empty()  # type: ignore


some_list: List[Any] = [1]

""" Unexpected type(s): (list, Matcher[Sized]) Possible types: (bool, str) (list, Matcher[list]) """
assert_that(some_list, is_(empty()))

""" All good: """
assert_that(some_list, is_(empty2()))

The same issue exists for most of the other collection matchers as far as i can tell.
(Sorry for accidentally hitting ´enter´ while writing my draft for the title, thus adding a issue without an explanation and a odd title at first).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions