-
-
Notifications
You must be signed in to change notification settings - Fork 108
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
Implement PEP 646 in typing_extensions #28
Comments
Thanks, Jelle. We were working on a runtime implementation in
https://github.com/python/cpython/pull/24527/files, but we could improve
the current PR (I'd added some comments there). We'd also need to support
`Unpack[Tuple[<foo>]]` as per the latest change.
If you're still interested in adding those, I'm happy to review. Otherwise,
I suppose Matthew or I will probably complete that PR over the coming
month.
(We will also need to land the `*Ts` syntax changes, but Matthew already
has a fork with the implementation
<https://github.com/mrahtz/cpython/tree/pep637%2B646>)
…On Thu, Nov 18, 2021 at 3:13 PM Shantanu ***@***.***> wrote:
I assume they use
https://github.com/facebook/pyre-check/blob/main/pyre_extensions/__init__.py
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<python/typing_extensions#28>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAC6L62VEXCH2YIIFKYXURDUMWCBLANCNFSM5IKZXLDQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
--
S Pradeep Kumar
|
(+1 to what Pradeep said.) |
Thanks! I agree with many of Pradeep's comments on that PR; it seems to add too many runtime checks. I'm happy to pick it back up and submit a new version to CPython and typing-extensions. |
Sounds good, Jelle, thanks!
…On Fri, Nov 19, 2021 at 5:14 AM Jelle Zijlstra ***@***.***> wrote:
Thanks! I agree with many of Pradeep's comments on that PR; it seems to
add too many runtime checks. I'm happy to pick it back up and submit a new
version to CPython and typing-extensions.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<python/typing_extensions#28>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAC6L674QEYBTRZAOGLXVKDUMZESBANCNFSM5IKZXLDQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
--
S Pradeep Kumar
|
That's very kind of you Jelle - thank you! How much of the CPython work were you intending to do - just the work in |
Full disclosure is that my main motivation is to be able to (ab)use So my plan would be:
You already have an implementation for the grammar changes, right? |
@JelleZijlstra looks like you're aiming to get a Context on why I care: I'm ready to start trying to get a proof-of-concept for callable syntax, but I realized a blocker is that I'm going to need a way to represent It seems like there may be no harm in putting up a PR on |
typing-extensions is harder, not easier, because it needs to deal with typing.py in older Python versions. I want to put it in typing-extensions first for two reasons: the PEP isn't accepted yet, so it doesn't make sense to put it in typing.py; and I'd like to be able to use the new features before Python 3.11 comes out. |
I see - I was just chatting with @pradeep90 and he said the PEP was just accepted (looks like not on the PEP page yet), which is why I was wondering about starting on typing right away, since it partially blocks my work. If it helps I could work on a PR based on @mrahtz's old code. I care more about |
Sorry for the slow reply - this thread dropped off my radar. Re status of the PEP - it was accepted, but then we realised there's one edge case yet to fix, and the Steering Council have said they want to review those changes before giving it the final stamp of approval. So it seems pretty likely that the final version will be accepted, but we're not quite there yet.
Yup, in https://github.com/mrahtz/cpython/tree/pep646-grammar. @stroxler, if you're wanting something in
Not sure whether that makes sense though given the work that @JelleZijlstra has already done - @JelleZijlstra, what do you think? |
@mrahtz I realized I'm probably not hard-blocked on Instead, what I'm going to need is to mimic the grammar changes inside a case of my callable type. But I also would like to check in about whether I could try an alternative implementation of the same grammar. After reading all of the docs on the parser and compiler, plus the implementation of PEP 604 using types.Union I am pretty convinced that we should add a This will allow us to get a A code snippet to illustrate what I mean: >>> import ast
>>> print(ast.dump(ast.parse("def f(*args: *Ts): ..."), indent=2))
Module(
body=[
FunctionDef(
name='f',
args=arguments(
posonlyargs=[], args=[],
vararg=arg(
arg='args',
annotation=Tuple( # this tuple is extraneous
elts=[
Starred( # the AST would make more sense if we get a Starred directly here
value=Name(id='Ts', ctx=Load()),
ctx=Load())],
ctx=Load())),
kwonlyargs=[], kw_defaults=[], defaults=[]),
body=[Expr(value=Constant(value=Ellipsis))], decorator_list=[])],
type_ignores=[]) I'm most concerned about the AST having an extra layer since that's what most tools will look at, but the enclosing Both these behaviors can be changed if we make an |
@stroxler this sounds like you're conflating two different things: what the AST looks like, and what it gets compiled to. The PEP says |
Hopefully it doesn’t have to be IDENTICAL? At runtime I want to be able to tell which one they typed. |
@gvanrossum that's what the PEP specifies: https://www.python.org/dev/peps/pep-0646/#change-2-args-as-a-typevartuple. I guess we could still change that (at the risk of further annoying the SC). As the author of a tool that would consume runtime annotations, I'm not particularly concerned about being able to tell the difference, though. Why do you think that's important? |
Because they mean different things to static checkers. |
Ah, yes @JelleZijlstra you're right it's explicitly called out. The pep is pretty long so I missed that sentence. I think this is weird and might be a mistake - having a nonexistent tuple in the AST is pretty confusing, and I wonder if it might cause major issues for concrete syntax trees like LibCST to have an "invisible" tuple node with no printable characters (I'd have to ask @zsol). But from a static type checker point of view we can live with it, the match statements will just be slightly ugly because of the nesting. It doesn't actually block any of my work, it just feels awkard - it seems like we didn't want to implement a compiler change therefore we're doing strange things instead (which is very understandable - adding a new type and opcode is much harder - but I think it's the right thing to do here). |
@gvanrossum's point kind of highlights why I find this a bit weird - we can't tell the difference in the Python AST between an explicit tuple with the star-expression (which I'm pretty sure we would naively expect type checkers to reject) and a bare star-for-unpack. It doesn't really matter as of this PEP because a TypeVarTuple or Tuple are the only legal things in that position and we can live with the ambiguity in this one form, but I'm afraid that there might be edge cases that box us in if we want to use starred expressions in other ways in the future (and I'm not talking about just typing changes, or just changes in the next 5 years - we'll have to live with invisible tuples forever). |
Reopening to track implementation of TypeVarTuple in typing-extensions. (The discussion of the AST is technically off topic here.) |
Sorry, I must have closed this by mistake. |
Alright, to check whether I understand so far, we're talking about two potential problems with the current behaviour of
Assuming my understand is correct, here's my take: It was indeed a deliberate decision on my part to have things work this way (including the extra Having said that, I'm sympathetic to argument 1; I'll admit that I didn't foresee the problem of runtime checkers not being able to tell the difference. But on that front, For argument 2, I have more mixed feelings. For the case of auto-formatters in particular, I'm leaning towards saying "It doesn't seem that bad for auto-formatters to just have to special-case this". For concerns along the lines of what @stroxler says:
I'm sympathetic to these concerns too, but I don't want us to be paralysed by fear of the unknown; there's always a risk that we'll accidentally commit to something that boxes us into something unfortunate, and I don't think there's any reason to think the risk here is higher than that baseline level of risk. I think the best we can do is try to mitigate the risk by asking "What specifically might it cause problems with?" - but if we can't come up with any answers to that, we should accept the risk and continue onwards for the sake of being able to make progress. (And again, there are costs in the other direction too in terms of delaying a PEP that's already taken > 1 year to build consensus over.) In the vein of asking "What specifically might it cause problems with if we want to use starred expressions in other ways in the future?" - to the extent that this is a problem with the way starred expressions are handled in Tl;dr: I agree it's non-ideal, but I think it's worth the tradeoff of not having to make more significant grammar changes and not delaying the PEP. |
Thanks for the summary! I don't see (1) as much of a problem. There are already many ways to write annotations that look the same to a runtime checker but would be rejected by a static checker: For (2), do I understand correctly that the AST for |
Oh, yikes, I didn't realise that was the case. Indeed, checking using the implementation at https://github.com/mrahtz/cpython/tree/pep646-grammar, the following:
do unfortunately both produce:
This admittedly does carry more weight for me; it's a shame we didn't catch this earlier. I lean towards still saying "This seems a sufficiently power-user feature that it's unlikely anyone would shoot themselves in the foot over this, so having mypy detect |
I think it makes sense to introduce a new AST node type to represent the |
Something else to consider here: I just realized that in the current implementation, the CPython unparser phase is guaranteed to create an explicit It's not clear whether that actually matters (most libraries interpreting types at runtime would presumably wind up evaluating the string anyway) but it could definitely surprise people. |
I don't think this is very relevant to the typing discussion, but since I've been summoned: If the currently proposed implementation gets merged, LibCST's CST will diverge from the AST in this case and will probably introduce a new node type, like @gvanrossum suggests above. There's already precedent for divergence like this, but they tend to cause friction for users of the library. |
Would we even need a new AST node? |
I agree with @JelleZijlstra, I'm pretty certain we don't need a new AST node unless we really want one. And I don't think we should add one if we can help it, using a bare We could probably compile it into either the equivalent of We might run into objections in code review if we do it that way, because we would have to make |
Okay, using a bare Starred node here should work fine.
|
Alright, I'll start working on the grammar/AST/compiler changes to make this happen. |
Ok, so this turned out to be easier than I expected; I've got a first attempt done in mrahtz/cpython@d76039a. Grammar: instead of
we just do
This is the only change needed compared to what's currently in the PEP. Compiler: instead of changing the implementation for The results are: AST:
As for
gives:
Does that fix everything we needed it to? |
@mrahtz I'm fine with that, but it's different from the behavior specified in the PEP (https://www.python.org/dev/peps/pep-0646/#change-2-args-as-a-typevartuple), which says that |
I think that fixes all the concerns. Agreed it requires updating the PEP language slightly. The precise bytecode we generate is an implementation detail, it might be worth asking advice on |
@JelleZijlstra Indeed, this would require another change to the PEP. @stroxler Alright, I've also been able to code up a @pradeep90 @gvanrossum Any opinions on this - By the way @stroxler @JelleZijlstra - Pradeep and I were thinking that implementation development could actually get a bit messy with the work being spread throughout three separate places. I've started https://github.com/mrahtz/cpython/tree/pep646 as the canonical source for the implementation - grammar changes, compiler changes, |
I haven't done any C work so far, only the draft typing-extensions implementation in python/typing#963 (which doesn't work yet in 3.6). |
I haven't done any work either. I'm happy to help out if there's anything you'd like to delegate but I didn't want us to have clashing changes. |
PEP 646 has been accepted (subject to some confusion about an edge case that's still being discussed), and we should have an implementation of it in typing-extensions.
@mrahtz @pradeep90 is there already a runtime implementation of PEP 646 somewhere? If not, I'd be happy to work on getting the right bits into typing-extensions and typing.
The text was updated successfully, but these errors were encountered: