Closed oTree-org closed 7 years ago
I'm not sure if this is really covariance as much as some simple generic manipulation. Off the top of my head, something like this might do the trick:
T = TypeVar('T', bound='BaseLeague:),
class BaseLeague(Generic[T]):
def get_teams(self) -> List[T]:
...
One problem with this method could be storing the League
objects, but that's another story. ;)
Thanks for the reply....so, I wrote this:
from typing import TypeVar, Generic
PlayerTV = TypeVar('PlayerTV', bound='BasePlayer')
TeamTV = TypeVar('TeamTV', bound='BaseTeam')
class BaseTeam(Generic[PlayerTV, TeamTV]):
def t(self) -> TeamTV: pass
def p(self) -> PlayerTV: pass
class BasePlayer(Generic[PlayerTV, TeamTV]):
def p(self) -> PlayerTV: pass
class Player(BasePlayer['Player', 'Team']):
real_attr = 1
class Team(BaseTeam[Player, 'Team']):
real_attr = 1
def m1(self):
a=self.t().real_attr
a=self.t().fake_attr
def m2(self):
a=self.p().real_attr
a=self.p().fake_attr
def f1(t: Team):
a=t.t().real_attr
a=t.t().fake_attr
When I run mypy mypy.py
, I get: mypy.py:30: error: "Team" has no attribute "fake_attr"
I would like it to flag all the lines referencing fake_attr
, but not real_attr
. It seems to only be working for the function but neither of the methods.
@oTree-org Mypy only type checks annotated methods. Since m1
and m2
don't have any type annotations, they aren't type checked. Try:
class Team(BaseTeam[Player, 'Team']):
real_attr = 1
def m1(self) -> None:
a=self.t().real_attr
a=self.t().fake_attr
def m2(self) -> None:
a=self.p().real_attr
a=self.p().fake_attr
OK thank you :)
I would like to know if Python type hinting (the
typing
module) supports return type covariance, mainly for PyCharm's autocompletion.Here are my base classes for my sports framework:
(There are many more methods I left out, like methods on BaseLeague returning BaseTeam/BasePlayer/BaseLeague objects, etc.)
I have multiple modules that subclass these 3 classes in parallel, and add/override methods and attributes.
In
hockey/models.py
, I have:And in
football/models.py
, I have the same thing:(I have 20+ other sports, like soccer, baseball, etc..)
In PyCharm, when I'm in
football.models.Team
and typeself.get_captain().
, PyCharm shows me the attributes for the base classBasePlayer
, but I would like it to show me the attributes for the subclassfootball.models.Player
. This seems closely related to return type covariance.I have a feeling I need to use
Generic
andTypeVar
like this:And then in
football.models
I would do something like:...where Player, Team, League are references to the subclasses in the same module.
But it's not working (PyCharm is not showing any autocomplete at all), and I'm not sure if I'm using the right syntax.
I would like to get this working because my base classes are part of my framework's API, and my users subclass them hundreds of times, so I'd like them to benefit from PyCharm autocomplete, without having to override each method in their own code.)
Does anyone know if this is possible?