You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My current plan is to postpone recursive types until simple structural subtyping is in and reconsider them later. After thinking about them more they are going to increase complexity a lot of I haven't seen much evidence for them being needed that often.
Reacted by Julian Bertram, Meyet Vivien, Zvonimir Erdelja, Tomasz Laskowski, Asger Hautop Drewsen, Topaz Guerrero, Filip Kaštovský, Kostiantyn Danylov aka koder, Dmitry Sitnikov, Noah Pederson and 7 more
If I'm understanding this issue right, I'm running into it for classes that want a fluent interface. So for example, if I want callers to do something like this:
myfoo.add(bar).add(baz).finish()
Then the definition of the Foo class and the add method need to look something like this:
classFoo:
defadd(self, x) ->Foo: # Python chokes on this line!# do stuffreturnself
Another place where Python commonly does return self is in the __enter__ method for context managers. Is mypy able to typecheck those right now?
@kirbyfan64, do you know if there are standard functions anywhere that understand this convention? Like, if I wanted to introspect a couple functions and compare the types of their arguments, should I handle the Foo == "Foo" case explicitly? That seems doable, but a string-aware version of say isinstance seems harder.
@oconnor663 I don't think there's anything like that. If you're introspecting the functions via a decorator, you could try accessing the caller's globals and locals.
There used to be an instance() implementation in typing.py but Mark Shannon
made me take it out. It's being deleted in this rev: python/typing@ac7494f
On Fri, Oct 16, 2015 at 9:37 AM, Ryan Gonzalez [email protected]
wrote:
@oconnor663https://github.com/oconnor663 I don't think there's
anything like that. If you're introspecting the functions via a decorator,
you could try accessing the caller's globals and locals.
—
Reply to this email directly or view it on GitHub #731 (comment).
Reacted by Esteban C Borsani, Iddan Aaronsohn, Max Kühn, Antti Kaihola, Hong Minhee (洪 民憙), Eric Arellano, Zac Hatfield-Dodds, Nick Williams, bwo, Cat Stevens and 17 more
I think this can now be closed by #13297 (and follow-up PRs). If there are remaining problems, they can be opened as separate issues.
Note this is only enabled in master with --enable-recursive-aliases (enables recursive type aliases, recursive TypedDicts, and recursive NamedTuples; as mentioned above proper classes and protocols can already be recursive). Note this is still considered an experimental feature, in particular type inference may sometimes fail, if this happens you can try switching to covariant collections, and/or simply give an explicit annotation.
Reacted by Shantanu, Jasha Sommer-Simpson, Lauren Yim, Mehdi Drissi, Kevin Orr, Benoit de Chezelles, Ben Spaulding, Emma Smith, Ruan Comelli, Niklas Lindström and 39 more
@ilevkivskyi is there a way to set this config option in a pyproject.toml file? I checked the documentation, but couldn't find anything about the new cli flag (perhaps because it's still experimental, and will eventually be enabled by default?)
Reacted by Neil Girdhar, Niklas Lindström, Cal Jacobson, Andreas Motl, Jasha Sommer-Simpson, Ben Spaulding, Nick Sweeting, Naglis Jonaitis and Brandon Stilson
Reacted by Cal Jacobson, Avasam, Warren Seine and Frank Sachsenheim
So with mypy>=1.7, recursive type support is built into mypy ✅
Reacted by Malcolm Greaves, Glyph, ThatXliner, Nikolai Røed Kristiansen, Piotr Dąbrowski, Gustavo Bezerra, Boris Naidis, Vladimir Lebedev, enpaul, Olivia Appleton-Crocker and 10 more
Reacted by Malcolm Greaves, Glyph, ThatXliner, Nikolai Røed Kristiansen, Piotr Dąbrowski, Bart Feenstra, Niklas Lindström, enpaul, Olivia Appleton-Crocker, Коренберг Марк and 5 more
Reacted by Malcolm Greaves, Glyph, Nikolai Røed Kristiansen, Olivia Appleton-Crocker, Коренберг Марк, Nick Sweeting, 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко), karlicoss and Brian Schubert
@jorenham Beware that this TypeAlias actually allows mixed lists, like [[1.2, 3.4], [[1.0, 0.0], [0.0, 1.0]]]. You might want to consider a non-recursive alias like S[float] | S[S[float]] | S[S[S[float]]] | S[S[S[S[float]]]] for a sufficient number of levels instead. The infinite union you probably want is currently not representable in the type system, I think.
You might want to consider a non-recursive alias like S[float] | S[S[float]] | S[S[S[float]]] | S[S[S[S[float]]]] for a sufficient number of levels instead.
In numpy the current maximum number of dimensions is 64, so that would indeed be possible. But in order to keep error messages from getting to long, and the type-checking from becoming to slow, I decided to go for this concise yet "broader" approach instead.
@jorenham Beware that this TypeAlias actually allows mixed lists, like [[1.2, 3.4], [[1.0, 0.0], [0.0, 1.0]]].
This made me realize that some of the numpy array-like type aliases in optype (that are heavily used in scipy-stubs) could be improved. Specifically, this affected the optype.numpy.To{Bool,JustInt,Int,Float,Complex,Array}{2,3}D type aliases (docs), which also accepted the mixed lists that you mentioned, @randolf-scholz. So now this has been fixed in optype 0.7.2 👌🏻.
Activity
JukkaL commentedon Aug 4, 2015
If (or when) mypy will have structural subtyping, recursive types would also be useful there.
JukkaL commentedon Oct 13, 2015
My current plan is to postpone recursive types until simple structural subtyping is in and reconsider them later. After thinking about them more they are going to increase complexity a lot of I haven't seen much evidence for them being needed that often.
oconnor663 commentedon Oct 16, 2015
If I'm understanding this issue right, I'm running into it for classes that want a fluent interface. So for example, if I want callers to do something like this:
Then the definition of the
Fooclass and theaddmethod need to look something like this:Another place where Python commonly does
return selfis in the__enter__method for context managers. Is mypy able to typecheck those right now?refi64 commentedon Oct 16, 2015
@oconnor663 Try:
oconnor663 commentedon Oct 16, 2015
Ah, thank you.
oconnor663 commentedon Oct 16, 2015
@kirbyfan64, do you know if there are standard functions anywhere that understand this convention? Like, if I wanted to introspect a couple functions and compare the types of their arguments, should I handle the
Foo == "Foo"case explicitly? That seems doable, but a string-aware version of sayisinstanceseems harder.refi64 commentedon Oct 16, 2015
@oconnor663 I don't think there's anything like that. If you're introspecting the functions via a decorator, you could try accessing the caller's globals and locals.
gvanrossum commentedon Oct 16, 2015
You're aware of typing.get_type_hints(obj)
right? It is similar toobj.annotations` but expands forward references.https://docs.python.org/3/library/typing.html?highlight=typing#typing.get_type_hints
There used to be an instance() implementation in typing.py but Mark Shannon
made me take it out. It's being deleted in this rev:
python/typing@ac7494f
On Fri, Oct 16, 2015 at 9:37 AM, Ryan Gonzalez [email protected]
wrote:
--Guido van Rossum (python.org/~guido)
oconnor663 commentedon Oct 16, 2015
@gvanrossum that's exactly what I was looking for, thanks. Sorry for the n00b questions today, but awesome that all this is supported.
JukkaL commentedon Oct 17, 2015
Mypy should detect missing string literal escapes (see #948).
dmoisset commentedon Aug 18, 2016
Going back to the original point on the issue, I found a case in the stdlib where this would be needed; the type for
isinstance()is currently:but it should actually be:
Because according to https://docs.python.org/3/library/functions.html#isinstance the tuples can be nested. I found an actual example of this while typechecking
django.http.response.HttpResponse.content80 remaining items
ilevkivskyi commentedon Aug 12, 2022
I think this can now be closed by #13297 (and follow-up PRs). If there are remaining problems, they can be opened as separate issues.
Note this is only enabled in master with
--enable-recursive-aliases(enables recursive type aliases, recursive TypedDicts, and recursive NamedTuples; as mentioned above proper classes and protocols can already be recursive). Note this is still considered an experimental feature, in particular type inference may sometimes fail, if this happens you can try switching to covariant collections, and/or simply give an explicit annotation.cj81499 commentedon Sep 27, 2022
@ilevkivskyi is there a way to set this config option in a
pyproject.tomlfile? I checked the documentation, but couldn't find anything about the new cli flag (perhaps because it's still experimental, and will eventually be enabled by default?)ilevkivskyi commentedon Sep 28, 2022
Yes, it is indeed a temporary flag (for few releases), and in 0.990 it will be on by default, you can try
This worked for me on Linux.
fix: use a correct recursive definition for DumperKey
bartfeenstra commentedon Nov 29, 2022
It appears that v0.990/v0.991 may not have addressed the entirety of the challenge that is recursive/cyclic types: #14219
jamesbraza commentedon Jul 30, 2024
For those reading in posterity:
mypy==0.981added--enable-recursive-alias: Enable recursive type aliases behind a flag #13297mypy==0.990started a deprecation cycle for--enable-recursive-alias: Temporarily put back --enable-recursive-aliases (as depreceated) #13852mypy==1.7.0completed the deprecation cycle, removing--enable-recursive-alias: Delete recursive aliases flags #16346So with
mypy>=1.7, recursive type support is built intomypy✅jorenham commentedon Nov 24, 2024
It doesn't work in this case:
https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=da0434e6062956cfd667a9e8c8bd3ff9
brianschubert commentedon Nov 24, 2024
@jorenham Thanks for the report! Can you please open a new issue?
randolf-scholz commentedon Nov 24, 2024
@jorenham Beware that this
TypeAliasactually allows mixed lists, like[[1.2, 3.4], [[1.0, 0.0], [0.0, 1.0]]]. You might want to consider a non-recursive alias likeS[float] | S[S[float]] | S[S[S[float]]] | S[S[S[S[float]]]]for a sufficient number of levels instead. The infinite union you probably want is currently not representable in the type system, I think.EDIT: we would need inductive types. If
typing.Mapis introduced(python/typing#1216, python/typing#1383, pre-pep discussion), then we should be able to express this as
jorenham commentedon Nov 24, 2024
In numpy the current maximum number of dimensions is 64, so that would indeed be possible. But in order to keep error messages from getting to long, and the type-checking from becoming to slow, I decided to go for this concise yet "broader" approach instead.
jorenham commentedon Nov 24, 2024
🫡 #18184
jorenham commentedon Nov 25, 2024
This made me realize that some of the numpy array-like type aliases in
optype(that are heavily used inscipy-stubs) could be improved. Specifically, this affected theoptype.numpy.To{Bool,JustInt,Int,Float,Complex,Array}{2,3}Dtype aliases (docs), which also accepted the mixed lists that you mentioned, @randolf-scholz. So now this has been fixed inoptype 0.7.2👌🏻.