-
Notifications
You must be signed in to change notification settings - Fork 81
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
Type hint broken for inject.attr when using ABCMeta #69
Comments
Hi! Thank you for a detailed explanation. I'll try to research the issue today or tomorrow and write back. |
I have found a workaround for this, but it's not pretty. from typing import cast
class Test:
service = cast(BaseService, inject.attr(BaseService))
def test(self) -> None:
self.service.f() # No error occurs now By using the cast function from the |
I suppose another workaround could be: T = TypeVar("T", bound=Type)
inject.attr = cast(Callable[[Type[T]], T], inject.attr) so you only have to do it once. |
With these type declarations: python-inject/inject/__init__.py Lines 107 to 108 in 05ad3e8
In combination with abstract base classes it seems that we're running into a very common problem: python/mypy#5374 (comment) |
@TheEdgeOfRage I haven't found any way how to solve this in |
I'm hitting this problem in an unrelated project and found a workaround which might help here as well. In python/mypy#4717, someone found out that you can use T = TypeVar("T", bound=Union[object, Any])
def attr(t: Callable[..., T]) -> T:
... It does smell like a horrible hack though ... |
Hey! Any update on this? I also stumbled upon this issue today ;) |
@AlTosterino Hi! I still know no way to fix this :-( Maybe, someone will find a way and make a PR. |
I'm not sure whether it's possible to do fix this at all, or whether it's an inherent Python thing. Also, just a heads up. This issue is only related to static type checking. It doesn't manifest itself in runtime.
I have an interface class (let's say
BaseService
) that hasABCMeta
as its metaclass with@abstractmethod
decorated empty methods. Several other classes (in my exampleService
) inherit from it and implement the methods.Then I have a factory function that instantiates one of the Implementations and returns it with the
BaseService
type hint. I use inject bind the factory to theBaseService
type.To resolve the dependency in another class I used
inject.attr(BaseService)
, but the returned value is type hinted asUnion[object, Any]
, instead ofBaseService
. This leads mypy to flag any code that uses the resolved dependency, saying that the object doesn't have any of the attributes thatBaseService
has.Here is a simple reproducible example:
Click to expand
As I said, this code works just fine when I run it through the CPython (3.8) interpreter. The problem is only related to mypy static checking. Running mypy on the code yields the following error:
If i instead remove
metaclass=ABCMeta
and the@abstractmethod
decorator fromBaseService
and use it as a normal base class, there is no issue. My guess is that theABCMeta
metaclass breaks the type hint for some reason, but I don't know enough about how it works to even make an educated guess.If this issue is not in fact rooted in this library, let me know and I'll open the issue elsewhere.
Thanks :)
The text was updated successfully, but these errors were encountered: