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
support pep 673 Self type #11871
Comments
FWIW, both pyright and pyre have implemented this feature in its currently-documented form if you want to play with it. |
I know :) it's great. I hate when people email SQLAlchemy with a feature request and say " django does it! " :) but yeah, just trying to see if people using mypy can take advantage also in the near term or if there's no roadmap for this one here. |
There is already a draft PR working on adding support for PEP 673: #11666 |
@AlexWaygood we are literally trying to choose right now if SQLAlchemy 2.0, for which we hope to have beta releases by the end of Q1 2022, can use pep673 Self or not. I know this is normally not something projects can estimate but is it your experience a PR like the one suggested in #11666 can move towards being merged within a few months or is it likely it could stall for a long time? |
at the same time, if we do release 2.0 using pep 673, mypy users would be more interested in seeing this PR completed so for that reason alone I might decide to use it now. |
Hey @zzzeek -- unfortunately, I'm not really the right person to ask about this :// I'm not actually on the mypy core team, and have only contributed a few documentation fixes to mypy -- I tend to contribute more towards the CPython & typeshed repos, I just stalk the mypy issue tracker from time to time Having said that, I think the approach typeshed has taken would probably serve you well! You could define a single # typing_utils.py
from typing import TypeVar
Self = TypeVar('Self') Then, in the rest of your code base, you could use that # foo.py
from typing_utils import Self
class Foo:
def returns_self(self: Self) -> Self:
return self
@classmethod
def returns_cls(cls: type[Self]) -> type[Self]:
return cls In that way, you'd get type annotations that work perfectly for now; and if PEP 673 is accepted and implemented, you could quite easily run a single script using AST to clean up your code base, converting # foo.py
from typing_extensions import Self
class Foo:
def returns_self(self) -> Self:
return self
@classmethod
def returns_cls(cls) -> type[Self]:
return cls The old version of |
I also just stalk the mypy issue tracker from time to time :-) I don't think there is anyone who gets paid time to work on mypy, so there isn't a concrete roadmap. In my experience, you can expect a lag time of a couple months from contributor-completes-PR to mypy-release-that-contains-said-PR. Re PEP 673 specifically: |
OK, we can certainly go with that, the approach we have at the moment is copied from how pep-673 illustrates it, with individual TypeVars that are each "bound" to the target type. There should be no reason that's needed though, right? that is, the "Self" that's not bound will work just as well? |
For situations like this, the It depends whether you're using mypy to check function implementations, or just writing stubs, though. If you're just writing stubs, you can get away with a lot more, and the |
this is inline typing in SQLAlchemy for 2.0 where we will no longer use stubs. |
In which case, yeah, you'll often need the from typing import TypeVar
FooSelf = TypeVar('F', bound='Foo')
class Foo:
bar: int
def change_bar(self: FooSelf, x: int) -> FooSelf:
self.bar = x # mypy erroneously complains about this line if the TypeVar is not bound
return self |
yes that's what we've been doing, thanks for the tips! |
No problem! |
Feature
Support the pep-673 Self type
pep is at: https://www.python.org/dev/peps/pep-0673/
a rough idea of it is that this code:
is quasi-equivalent to:
Pitch
the appeal of the pep is that for the very common pattern of method-chained object construction, methods can easily indicate they return an object of the same type upon which the method is being invoked. For example if I made
class SubWidget(Widget)
, theSubWidget.add_thing()
method reportsSubWidget
as the return type automatically. The pattern using TypeVar seems to be more or less equivlant, but is more verbose requiring the declaration of TypeVar objects per class hierarchy as well as that it has to be explicitly present on the "self" parameter in methods.We are looking for this feature to make our job of integrating typing into SQLAlchemy an easier job. it seems to be a fairly straightforward translation between two idioms.
cc @CaselIT
The text was updated successfully, but these errors were encountered: