[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Batuhan Taskaya
> Has anyone considered adding a new special method like `__arrow__` or 
> something, that would be user-definable, but also defined for tuples and 
> types as returning a Callable? For example `int -> str` could mean 
> Callable[[int], str], and (int, str) -> bool could mean Callable[[int, str], 
> bool]. I would find that sort of semantics more agreeable since Python 
> already has operators that dispatch to dunder methods, and anyone who knows 
> how that bit of Python works would automatically mostly know how the new 
> operator works.

I would personally argue that this would make the situation worse,
considering the complexity would be increased with no possible use
case on the route beside type annotations.

On Thu, Jan 13, 2022 at 7:30 AM Dennis Sweeney
 wrote:
>
> Like others expressed, I don't like the idea of the typing and non-typing 
> parts of Python separating.
>
> Has anyone considered adding a new special method like `__arrow__` or 
> something, that would be user-definable, but also defined for tuples and 
> types as returning a Callable? For example `int -> str` could mean 
> Callable[[int], str], and (int, str) -> bool could mean Callable[[int, str], 
> bool]. I would find that sort of semantics more agreeable since Python 
> already has operators that dispatch to dunder methods, and anyone who knows 
> how that bit of Python works would automatically mostly know how the new 
> operator works.
>
> If I understand right, this is a sort of combination of two things for which 
> there is more precedent: first, adding a new operator based on the needs of a 
> subset of users (the @ operator and __matmul__), and second, adding new 
> operators to existing objects for the sake of typing (like the list[int] 
> syntax in which type.__getitem__ was implemented to dispatch to 
> the_type.__class_getitem__).
>
> If people don't want to add a new operator and dunder, I assume using the 
> right shift operator like `(int, bool) >> str` would be too cheesy?
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/GTYLK4QA6DHQDZH7NLYLELYCFUKOTNDT/
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/GDLOI64UZRCSG7GGSNM67MSKFWQ4LI5B/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Nick Coghlan
On Thu, 13 Jan 2022, 2:24 pm Dennis Sweeney, 
wrote:

> Like others expressed, I don't like the idea of the typing and non-typing
> parts of Python separating.
>
> Has anyone considered adding a new special method like `__arrow__` or
> something, that would be user-definable, but also defined for tuples and
> types as returning a Callable? For example `int -> str` could mean
> Callable[[int], str], and (int, str) -> bool could mean Callable[[int,
> str], bool]. I would find that sort of semantics more agreeable since
> Python already has operators that dispatch to dunder methods, and anyone
> who knows how that bit of Python works would automatically mostly know how
> the new operator works.
>

If such a protocol were to be proposed, then int.__arrow__ could be defined
such that "1 -> 100" was equivalent to "range(1, 100)" (in addition to the
typing use cases).


The existing section on runtime behaviour in the PEP doesn't look ready for
SC consideration, since it essentially says "this hasn't been defined yet".

Cheers,
Nick.


>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/ENTIEFGCG7O7APREWRLKAX72DISHXSNT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Steven D'Aprano
On Thu, Jan 13, 2022 at 06:41:14PM +1000, Nick Coghlan wrote:

> If such a protocol were to be proposed, then int.__arrow__ could be defined
> such that "1 -> 100" was equivalent to "range(1, 100)"

Why? What's the benefit? It is slightly shorter, but no more clear than 
range. I would never guess that `1 -> 100` would mean a range object. I 
would think it was a transformation of 1 -> 100.

In e.g. Ruby the equivalent of range has syntax 1...100, which matches 
how we write ranges of values in English.

If we had an arrow operator beyond the typing proposal, I think it would 
be a terrible wasted opportunity to use it for something as unclear and 
trivial as a range object :-(


-- 
Steve
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/L6XT3PVYSUKTA6PZDPKLGATXA32NT5AB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Paul Moore
On Thu, 13 Jan 2022 at 08:48, Nick Coghlan  wrote:
>
> The existing section on runtime behaviour in the PEP doesn't look ready for 
> SC consideration, since it essentially says "this hasn't been defined yet".

+1. The runtime behaviour needs to be specified. Otherwise this PEP is
a spec for how type checkers work, but it fails to say how CPython
itself will work :-(

Paul
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/DR5WITUYO4MA5GADVQLQFUFDTKY26LN4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Steven D'Aprano
On Thu, Jan 13, 2022 at 04:23:09AM -, Dennis Sweeney wrote:

> Like others expressed, I don't like the idea of the typing and 
> non-typing parts of Python separating.

Its a good thing that this PEP doesn't separate the typing and 
non-typing world. The arrow syntax will be a plain old Python expression 
that is usable anywhere, not just in annotations.

It will only be *useful* in code that makes use of generic types, 
whether that is for annotations or runtime introspection, or exploration 
in the REPL, but that's okay. `is` is a built-in operator despite have 
exceedingly limited use-cases and sometimes being an attractive 
nuisance.


> Has anyone considered adding a new special method like `__arrow__` or 
> something, 

In the absense of any useful functionality for this arrow syntax, I 
think that is a clear case of YAGNI.

As it turns out, I do have a use-case for an arrow operator, but it 
wouldn't use a dunder either. And since my use-case doesn't have a PEP 
written, it would be unfair of me to derail the conversation with a 
half-baked proposal that is nowhere near ready to be a PEP.

But if it gets rejected, all bets are off :-)

If you do have some non-trivial uses for the arrow operator, it would be 
good to hear what they are.


> that would be user-definable, but also defined for tuples 
> and types as returning a Callable? For example `int -> str` could mean 
> Callable[[int], str], and (int, str) -> bool could mean Callable[[int, 
> str], bool].

That wouldn't work. The PEP explains that they don't want people to 
be able to write:

int -> bool

without the parentheses. I agree with them. I think it is important that 
the syntax be visually similar to an anonymous function signature with 
the parameter names scrubbed out:

def func(a:int) -> str

https://www.python.org/dev/peps/pep-0677/#parenthesis-free-syntax

Analogy: we require generator comprehensions to be surrounded by 
parentheses:

it = (expr for i in sequence)

In the desired syntax:

   (int) -> bool

that is not a tuple. Its a parenthesised comma-separated expression.

The same objection applies to using the `>>` operator. There is no way 
to force `(int) >> str` or prevent `int >> str`.


> I would find that sort of semantics more agreeable since 
> Python already has operators that dispatch to dunder methods,

And Python already has operators which don't:

- `or` and `and`
- `is` and `is not`
- name binding (assignment) `=`
- walrus assignment operator `:=`
- ternary `if else` operator.

So there is plenty of precedent for dunder-less operators.



-- 
Steve
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/W7Y4Z7M7QBJXKRE6IL6LEIVUSFNVFRE4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Petr Viktorin

On 12. 01. 22 17:58, Guido van Rossum wrote:
On Wed, Jan 12, 2022 at 4:57 AM Petr Viktorin > wrote:


Matthew Rahtz wrote:
 > Hi everyone,
 >
 > We've got to the stage now with PEP 646 that we're feeling pretty
happy
 > with it. So far though we've mainly been workshopping it in
typing-sig, so
 > as PEP 1 requires we're asking for some feedback here too before
submitting
 > it to the steering council.
 >
 > If you have time over the next couple of weeks, please take a
look at the
 > current draft and let us know your thoughts:
 > https://www.python.org/dev/peps/pep-0646/
 (Note that the final
couple of
 > sections are out of date;
https://github.com/python/peps/pull/1880

 > clarifies which grammar changes would be required, now that PEP
637 has
 > been rejected. We also have a second PR in progress at
 > https://github.com/python/peps/pull/1881
 clarifying some of the
motivation.)
 >
 > Thanks!
 > Matthew and Pradeep

Hi,
I'm very late to the discussion -- I relied on the typing-sig and SC to
handle this, but now that I'm on the SC, I no longer have that luxury :)
This mail has my own opinions, not necessarily the SC's.


I've read the PEP, and I quite like it! It's clear that typing-sig
thought this through very well.
The thing that surprised me is the proposed changes that affect more
than typing annotations. Quite deep in the PEP, the "Grammar Changes"
section explains the (quite exciting) change to make star-unpacking
possible in normal indexing operations, e.g.::

      idxs_to_select = (1, 2)
      array[0, *idxs_to_select, -1]  # Equivalent to [0, 1, 2, -1]

However, the PEP is silent about indexing assignment, e.g.::

      array[0, *idxs_to_select, -1] = 1

IMO, it would be very confusing to not keep these in sync. If they are,
the assignment change should be documented and tested appropriately. Is
that the plan?


The previous SC approved the PEP despite this.

If you want to convince the SC to request this feature parity in the 
PEP, I won't stop you.


But unless that happens I would rather not update the PEP again (it's 
been tough to get to this point).


Maybe you can write a separate PEP? That would probably be simpler for 
all involved (the PEP 646 authors would not have to be involved, and the 
separate PEP would be very straightforward.


As I learned after drafting that question, at least some members of the 
previous SC feel like this went without saying. So I'm a bit surprised 
by this reply. Guess it goes to show that PEPs need to be precise :)


Looking at the current grammar, I see that the proposed change to 
`slices` will affect indexed assignment. And the reference 
implementation also allows it.


With that in mind, can we treat this as this as a clarification, rather 
than a substantial change? A simple note that indexed assignment is also 
affected should be enough. (Tests/docs in the eventual implementation 
won't be so simple, but they'll be needed anyway.)


Of course, if __setitem__ isn't meant to be affected, the proposed 
grammar change needs to be revisited.




For a second point, the PEP says:

 > this PEP disallows multiple unpacked TypeVarTuples within a
single type parameter list. This requirement would therefore need to
be implemented in type checking tools themselves rather than at the
syntax level.

Typing annotations are sometimes used for other things than *static*
typing, and I wouldn't be surprised if type checkers themselves started
allowing this (as a non-standard extension in cases where things aren't
ambiguous):

      def tprod(Generic[*T1], Generic[*T2]) -> Generic[*T1, *T2]: ...


I don't think that sentence is trying to forbid this. The problem 
appears in things like


def foo(*args: tuple[*Ts1, *Ts2]) -> ...

Maybe the wording in the PEP can be imrpoved?


Looks like it can -- the current wording does forbid it:


As of this PEP, only a single type variable tuple may appear in a type 
parameter list


But improving that smells like a rabbit hole. It's probably better to 
keep it disallowed (as a static typing expression) in the current PEP.



If multiple unpackings in a tuple aren't blocked by the compiler, they
should be tested and documented as syntactically valid annotations --
just not valid static typing annotations (even though other uses are
currently deprecated). In particular, once the compiler allows multiple
unpackings, disallowing them at the syntax level later would mean
breaking backwards compatibility.
Do we share that view?


Agreed that the syntax with multiple stars will not be deprecated at 
runtime, but type checkers may reje

[Python-Dev] Re: Minor inconvenience: f-string not recognized as docstring

2022-01-13 Thread Steve Holden
On Tue, Jan 11, 2022 at 6:24 PM Guido van Rossum  wrote:

> I personally think F-strings should not be usable as docstrings. If you
> want a dynamically calculated docstring you should assign it dynamically,
> not smuggle it in using a string-like expression. We don't allow "blah {x}
> blah".format(x=1) as a docstring either, not "foo %s bar" % x.
>

I came to the conclusion that something like jinja2, operating on a Python
template, was a better way to go.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/OK7HQ44SIWDRDHZPKPCNKUJ4YAZ5QGXK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Kevin Millikin via Python-Dev
The wording there probably should be improved.  I had a different
interpretation when I read that, so that suggests it needs to be clarified.

We should ensure to draw a clear distinction between type parameters and
type arguments.  (Generic classes and functions are parameterized over type
parameters and they have a type parameter list that is implicit in the
syntax.  Generic classes can be explicitly instantiated by giving them type
arguments, and an instantiation has a (explicit or implicit) type argument
list.)

So when I read:

"""
As of this PEP, only a single type variable tuple may appear in a type
parameter list:

class Array(Generic[*Ts1, *Ts2]): ...  # Error\
"""

I interpreted it to mean that the error is that the type _parameters_ of
the generic class Array include *Ts1 and *Ts2 (not that they were used as
type arguments to Generic).  Similarly, this should be an error:

class Array(dict[*Ts1], Generator[*Ts2]): ...

even though there is only a single type variable tuple appearing in a type
_argument_ list.

The reason for the restriction is that the tupling of Array's type
arguments is not explicit in an instantiation of Array, so we rely on this
restriction so that they can be unambiguously tupled.

I don't think there is necessarily a similar restriction on a generic
function's type parameters, because we don't have the ability to explicitly
instantiate generic functions anyway.

An alternative wording is along the lines of: "As of this PEP, only a
single type variable tuple may appear among a generic class's type
parameters."

def foo(*args: tuple[*Ts1, *Ts2]) -> ...

is already prohibited by "Multiple Unpackings in a Tuple: Not Allowed".

There are three other occurrences of "type parameter list" in the PEP.  Two
of them talk about instantiating generic type aliases and should be changed
to "type argument list".  The last one is less clear, I can't quite parse
out what it's trying to say.

On Wed, Jan 12, 2022 at 5:04 PM Guido van Rossum  wrote:

> On Wed, Jan 12, 2022 at 4:57 AM Petr Viktorin  wrote:
>
>> Matthew Rahtz wrote:
>> > Hi everyone,
>> >
>> > We've got to the stage now with PEP 646 that we're feeling pretty happy
>> > with it. So far though we've mainly been workshopping it in typing-sig,
>> so
>> > as PEP 1 requires we're asking for some feedback here too before
>> submitting
>> > it to the steering council.
>> >
>> > If you have time over the next couple of weeks, please take a look at
>> the
>> > current draft and let us know your thoughts:
>> > https://www.python.org/dev/peps/pep-0646/ (Note that the final couple
>> of
>> > sections are out of date; https://github.com/python/peps/pull/1880
>> > clarifies which grammar changes would be required, now that PEP 637 has
>> > been rejected. We also have a second PR in progress at
>> > https://github.com/python/peps/pull/1881 clarifying some of the
>> motivation.)
>> >
>> > Thanks!
>> > Matthew and Pradeep
>>
>> Hi,
>> I'm very late to the discussion -- I relied on the typing-sig and SC to
>> handle this, but now that I'm on the SC, I no longer have that luxury :)
>> This mail has my own opinions, not necessarily the SC's.
>>
>>
>> I've read the PEP, and I quite like it! It's clear that typing-sig
>> thought this through very well.
>> The thing that surprised me is the proposed changes that affect more
>> than typing annotations. Quite deep in the PEP, the "Grammar Changes"
>> section explains the (quite exciting) change to make star-unpacking
>> possible in normal indexing operations, e.g.::
>>
>>  idxs_to_select = (1, 2)
>>  array[0, *idxs_to_select, -1]  # Equivalent to [0, 1, 2, -1]
>>
>> However, the PEP is silent about indexing assignment, e.g.::
>>
>>  array[0, *idxs_to_select, -1] = 1
>>
>> IMO, it would be very confusing to not keep these in sync. If they are,
>> the assignment change should be documented and tested appropriately. Is
>> that the plan?
>>
>
> The previous SC approved the PEP despite this.
>
> If you want to convince the SC to request this feature parity in the PEP,
> I won't stop you.
>
> But unless that happens I would rather not update the PEP again (it's been
> tough to get to this point).
>
> Maybe you can write a separate PEP? That would probably be simpler for all
> involved (the PEP 646 authors would not have to be involved, and the
> separate PEP would be very straightforward.
>
>
>> For a second point, the PEP says:
>>
>> > this PEP disallows multiple unpacked TypeVarTuples within a single type
>> parameter list. This requirement would therefore need to be implemented in
>> type checking tools themselves rather than at the syntax level.
>>
>> Typing annotations are sometimes used for other things than *static*
>> typing, and I wouldn't be surprised if type checkers themselves started
>> allowing this (as a non-standard extension in cases where things aren't
>> ambiguous):
>>
>>  def tprod(Generic[*T1], Generic[*T2]) -> Generic[*T1, *T2]: ...
>>
>
> I don't think that sentence is t

[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Steven Troxler
Good catch, thanks Nick!
It's been specified in a linked doc [0] but I forgot to move that into the PEP 
itself.
I'll aim to get that done today.
---
[0] 
https://docs.google.com/document/d/15nmTDA_39Lo-EULQQwdwYx_Q1IYX4dD5WPnHbFG71Lk/edit
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/GLRQUR76I4UTH4YBTBNAB54CYEMFRD6W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Steven Troxler
Using an operator is an interesting idea, and we should probably call it out as 
an alternative in the PEP.
It's not a substitute for the current PEP from the standpoint of typing-sig for 
a few reasons:

(A) We care that the syntax be forward-compatible with supporting named 
arguments, as outlined in the "Extended Syntax" section of Rejected 
Alternatives and I don't think an operator-based syntax would extend to that.

(B) We  like supporting `(**P) -> bool` and `(int, **P) -> bool` for PEP 612 
ParamSpec and Concatenate; this makes it much easier to write types for 
decorators, which are a common use case. It would be tricky to do this using an 
arrow operator.

(C) I'd hesitate to add a dunder method on the tuple type, for reasons already 
mentioned here as well as the fact that it would force us to write unary 
callables - which are the most common kind - as `(int,) >> bool`

--

Separate from the question of arrow types, I wonder if an arrow operator would 
be worthwhile; I don't think it would have to be just for typing.

Discussion probably belongs in a separate thread and I'd be happy to kick one 
off, but it sounds like Steve has a potential use case and I've always found 
the use of `>>`, which feels very low-level because it has baggage as a 
bit-shift, in DSLs to be a little weird. Proposing an operator like `=>` or 
`|>` (my preference would be not to use `->`) might make sense.

The DSLs I'm thinking of (coming from data science) are all, loosely speaking, 
about some kind of pipelining
- dplython uses `>>` to mimic R's pipeline operator, which works well for 
certain data transformations
- At least at one point airflow supported creating DAG links using `>>` to 
represent control flow
- As far as I know Tensorflow doesn't currently use `>>`, but their curried API 
that would lend itself to this
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/NIYHXMFKLN5C47ZIHBF7M4KSFJLZFDMQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 677 (Callable Type Syntax): Final Call for Comments

2022-01-13 Thread Chris Angelico
On Fri, Jan 14, 2022 at 2:12 AM Steven Troxler  wrote:
>
> Using an operator is an interesting idea, and we should probably call it out 
> as an alternative in the PEP.
> It's not a substitute for the current PEP from the standpoint of typing-sig 
> for a few reasons:
>
> (A) We care that the syntax be forward-compatible with supporting named 
> arguments, as outlined in the "Extended Syntax" section of Rejected 
> Alternatives and I don't think an operator-based syntax would extend to that.
>
> (B) We  like supporting `(**P) -> bool` and `(int, **P) -> bool` for PEP 612 
> ParamSpec and Concatenate; this makes it much easier to write types for 
> decorators, which are a common use case. It would be tricky to do this using 
> an arrow operator.
>

Ah, good point(s), so it wouldn't really work unless there could be
some dict/tuple hybrid and that would be a much bigger change.

> (C) I'd hesitate to add a dunder method on the tuple type, for reasons 
> already mentioned here as well as the fact that it would force us to write 
> unary callables - which are the most common kind - as `(int,) >> bool`

This one's easily solved with a reflected dunder though - "(x,y,z) +
q" can be handled by q.__radd__ without any help from the tuple. But
yeah, it'd only work for tuples, so that's the end of that theory. Oh
well.

ChrisA
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/IWX6HY34E7ZKVPIOZG6YKI7MKO7LRUSS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Fwd: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Matthew Rahtz via Python-Dev
Thanks for this feedback, Petr!

*First point (indexing assignment)*

Great catch; we hadn't thought about this. I agree it would be better to
keep these in sync.

I just tested this in our current CPython implementation, and can confirm
it looks like this already works fine. So as much as I agree with Guido in
preferring not to make too many more updates to the PEP, I guess we can
indeed just fix this with a small clarification. I'll also add some tests
for this to our CPython implementation.

*Second point (multiple TypeVarTuples)*

In terms of the wording in the PEP - Guido, our intention actually *was* to
prohibit even the straightforward cases for now. Iirc, our reasoning was
that we thought the decision boundary between "straightforward to infer
type assignment" and "nontrivial to infer type assignment" (and of course
"no unique type assignment") was tricky enough that we shouldn't complicate
the already-long PEP by trying to describe all the cases where it was and
wasn't ok.

Petr, do I understand that the crux for you is basically that we should
commit to multiple-stars at the syntax level - the main implication being
to make sure we've properly documented and tested it? I'm happy with this;
we plan to follow up with another PEP that *does* talk about when multiple
unpackings are ok anyway. I guess we should just a) clarify in the PEP that
allowing multiple unpackings in the grammar isn't accidental, and b) test
this in our CPython implementation?

*Third point (aliases)*

This is actually a great point - I had to think about this myself.

Since PEP 484 doesn't explicitly spell out how assignment of type to type
variables in generic aliases works either, I had to try some things with
mypy playground to figure out what the current rules are. I think the logic
is, if we have an alias like

Foo = tuple[T1, T1, T2]
Foo[int, str]

then we construct a list of unique type variables in the alias (here [T1,
T2]), then assign types to those variables by going left to right through
the type argument list when the alias is instantiated. Guido, can you
remember from your time with mypy whether this is correct? Pradeep, I guess
you'll also know about this?

Based on that precedent, I believe that:

SplitDataset = Tuple[Array[*Ts], Array[*Ts]]
SplitDataset[Height]  # Valid; equivalent Tuple[Array[Height],
Array[Height]]

(indeed, I just tested this with Pyre, and that matches our implementation
there)

For this one:

TwoArrays = Tuple[Array[*Ts1], Array[*Ts2]]
TwoArrays[Height]

Since we we allow a TypeVarTuple to be bound to an *empty* list of types,
when we try to assign type arguments [Height] to the unique list of type
variables [Ts1, Ts2], I think we should end up with Ts1 containing Height
and Ts2 being empty; thus:

TwoArrays[Height]  # Valid; equivalent to Tuple[Array[Height], Array[()]]

But I actually can't get this to type check correctly in Pyre. Pradeep,
this is the test I was using:
https://gist.github.com/mrahtz/cc86c29538de1d4a80a2e8958ae71c5a Am I doing
something wrong?

Also, by that logic, in this situation *all* the type arguments would be
assigned to Ts1, and Ts2 would always end up being empty. That seems a bit
weird but...*shrug* it also seems correct.

In any case, this is definitely something we should explain better in the
PEP. I'll make a TODO for myself to write something on this once Pradeep
and Guido have confirmed whether my understanding is correct.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/3TGPEF465RBVLURM75RGRRR3627PXXNF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Guido van Rossum
On Thu, Jan 13, 2022 at 7:23 AM Matthew Rahtz  wrote:

> Thanks for this feedback, Petr!
>
> *First point (indexing assignment)*
>
> Great catch; we hadn't thought about this. I agree it would be better to
> keep these in sync.
>
> I just tested this in our current CPython implementation, and can confirm
> it looks like this already works fine. So as much as I agree with Guido in
> preferring not to make too many more updates to the PEP, I guess we can
> indeed just fix this with a small clarification. I'll also add some tests
> for this to our CPython implementation.
>

Agreed. I just misremembered this, my bad! Please do the clarification etc.


> *Second point (multiple TypeVarTuples)*
>
> In terms of the wording in the PEP - Guido, our intention actually *was* to
> prohibit even the straightforward cases for now. Iirc, our reasoning was
> that we thought the decision boundary between "straightforward to infer
> type assignment" and "nontrivial to infer type assignment" (and of course
> "no unique type assignment") was tricky enough that we shouldn't complicate
> the already-long PEP by trying to describe all the cases where it was and
> wasn't ok.
>
> Petr, do I understand that the crux for you is basically that we should
> commit to multiple-stars at the syntax level - the main implication being
> to make sure we've properly documented and tested it? I'm happy with this;
> we plan to follow up with another PEP that *does* talk about when
> multiple unpackings are ok anyway. I guess we should just a) clarify in the
> PEP that allowing multiple unpackings in the grammar isn't accidental, and
> b) test this in our CPython implementation?
>

I would love it for the cases where it's *not* ambiguous to just work (once
type checkers support it). I'd like the PEP to be written so as not to
disallow those. Type checkers that only support a single star even when
it's unambiguous should be considered out of compliance. (But could still
be fully compliant otherwise.) User pressure will then sort things out.

That seems better than requiring a follow-up PEP just to allow
non-ambiguous cases that follow the PEP's semantics.

FWIW I still feel we don't have a simple enough example to distinguish the
situations.

This should clearly be disallowed:

def f(*args: *tuple[*Ts1, *Ts2])...

This (and similar variants) should also be disallowed:

def f(*args: *tuple[*Ts, *Ts])...

This should be allowed:

def f(*args: *tuple[int, *Ts, str, T])...

But not this:

def f(*args: *tuple[*Ts1, str, *Ts2])...

(Even though there might be cases where it's unambiguous, like f(1, 2, 3,
"", 4, 5).)

It seems you are saying that this would be disallowed, even though there's
no ambiguity?

def f(a: Array[*Ts1], b: Array[*Ts2])...

I'm failing to see the point. (Other than that perhaps Pyre doesn't support
it? :-) The two positional (non-variadic!) arguments have different types,
each of which is an Array with variadic length. I can see nothing ambiguous
about this. If you indeed want to disallow this, can you show a scenario
where there's an ambiguity?

Also, in call sites I feel that multiple stars shouldn't be an issue.
Example:

def f(*args: *Ts)...

f(*Array[int, int], *Array[str, str])  # Ts becomes [int, int, str, str]



> *Third point (aliases)*
>
> This is actually a great point - I had to think about this myself.
>
> Since PEP 484 doesn't explicitly spell out how assignment of type to type
> variables in generic aliases works either, I had to try some things with
> mypy playground to figure out what the current rules are. I think the logic
> is, if we have an alias like
>
> Foo = tuple[T1, T1, T2]
> Foo[int, str]
>
> then we construct a list of unique type variables in the alias (here [T1,
> T2]), then assign types to those variables by going left to right through
> the type argument list when the alias is instantiated. Guido, can you
> remember from your time with mypy whether this is correct? Pradeep, I guess
> you'll also know about this?
>

Yes, that's how it works. Also, Foo[int] would be an error in that case.


> Based on that precedent, I believe that:
>
> SplitDataset = Tuple[Array[*Ts], Array[*Ts]]
> SplitDataset[Height]  # Valid; equivalent Tuple[Array[Height],
> Array[Height]]
>
> (indeed, I just tested this with Pyre, and that matches our implementation
> there)
>

Yeah, looks fine.

As a corollary, this would also be correct, right?

SplitDataSet[Height, Width]

and it would make Ts be (Height, Width). Right?


> For this one:
>
> TwoArrays = Tuple[Array[*Ts1], Array[*Ts2]]
> TwoArrays[Height]
>

Given the previous example and my corollary, this seems ambiguous, just
like `def f(*tuple[*Ts1, *Ts2])`.


> Since we we allow a TypeVarTuple to be bound to an *empty* list of types,
> when we try to assign type arguments [Height] to the unique list of type
> variables [Ts1, Ts2], I think we should end up with Ts1 containing Height
> and Ts2 being empty; thus:
>
> TwoArrays[Height]  # Valid; equivalent to Tuple[Array[He

[Python-Dev] Re: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Guido van Rossum
On Thu, Jan 13, 2022 at 8:18 AM Matthew Rahtz  wrote:

> Thanks also Kevin for this feedback!
>
> Good point about being careful to distinguish type parameters vs type
> arguments. If I understand correctly, you're making two points:
>
> 1. The wording of the 'Multiple Type Variable Tuples: Not Allowed' section
> - you're saying that we're being a bit imprecise here in saying that we
> disallow multiple TypeVarTuples in a type parameter list, given that in
> e.g. `def f(x: *Ts1, y: *Ts2)`, both Ts1 and Ts2 are members of the
> parameter list for the function f, but there it's unambiguous, so in fact
> it *is* allowed.
>

That looks like a syntax error. We only allow *Ts if the argument is of the
form *a. `def f(x: *Ts1)` is not allowed.

Maybe you were thinking of `def f(x: Array[*Ts1], y: Array[*Ts2]) as the
example? That seems unambiguous since the two positional arguments are
given separately.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/KFLFRX6PWDEEFXKL77UZJAADMK4YKDF7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 646 (Variadic Generics): final call for comments

2022-01-13 Thread Matthew Rahtz via Python-Dev
Thanks also Kevin for this feedback!

Good point about being careful to distinguish type parameters vs type
arguments. If I understand correctly, you're making two points:

1. The wording of the 'Multiple Type Variable Tuples: Not Allowed' section
- you're saying that we're being a bit imprecise here in saying that we
disallow multiple TypeVarTuples in a type parameter list, given that in
e.g. `def f(x: *Ts1, y: *Ts2)`, both Ts1 and Ts2 are members of the
parameter list for the function f, but there it's unambiguous, so in fact
it *is* allowed.

2. Use of wrong terminology elsewhere in the PEP. Agreed.

I'll draft a PR tweaking the wording to fix both these points.


On Thu, 13 Jan 2022 at 11:28, Kevin Millikin  wrote:

> The wording there probably should be improved.  I had a different
> interpretation when I read that, so that suggests it needs to be clarified.
>
> We should ensure to draw a clear distinction between type parameters and
> type arguments.  (Generic classes and functions are parameterized over type
> parameters and they have a type parameter list that is implicit in the
> syntax.  Generic classes can be explicitly instantiated by giving them type
> arguments, and an instantiation has a (explicit or implicit) type argument
> list.)
>
> So when I read:
>
> """
> As of this PEP, only a single type variable tuple may appear in a type
> parameter list:
>
> class Array(Generic[*Ts1, *Ts2]): ...  # Error\
> """
>
> I interpreted it to mean that the error is that the type _parameters_ of
> the generic class Array include *Ts1 and *Ts2 (not that they were used as
> type arguments to Generic).  Similarly, this should be an error:
>
> class Array(dict[*Ts1], Generator[*Ts2]): ...
>
> even though there is only a single type variable tuple appearing in a type
> _argument_ list.
>
> The reason for the restriction is that the tupling of Array's type
> arguments is not explicit in an instantiation of Array, so we rely on this
> restriction so that they can be unambiguously tupled.
>
> I don't think there is necessarily a similar restriction on a generic
> function's type parameters, because we don't have the ability to explicitly
> instantiate generic functions anyway.
>
> An alternative wording is along the lines of: "As of this PEP, only a
> single type variable tuple may appear among a generic class's type
> parameters."
>
> def foo(*args: tuple[*Ts1, *Ts2]) -> ...
>
> is already prohibited by "Multiple Unpackings in a Tuple: Not Allowed".
>
> There are three other occurrences of "type parameter list" in the PEP.
> Two of them talk about instantiating generic type aliases and should be
> changed to "type argument list".  The last one is less clear, I can't quite
> parse out what it's trying to say.
>
> On Wed, Jan 12, 2022 at 5:04 PM Guido van Rossum  wrote:
>
>> On Wed, Jan 12, 2022 at 4:57 AM Petr Viktorin 
>> wrote:
>>
>>> Matthew Rahtz wrote:
>>> > Hi everyone,
>>> >
>>> > We've got to the stage now with PEP 646 that we're feeling pretty happy
>>> > with it. So far though we've mainly been workshopping it in
>>> typing-sig, so
>>> > as PEP 1 requires we're asking for some feedback here too before
>>> submitting
>>> > it to the steering council.
>>> >
>>> > If you have time over the next couple of weeks, please take a look at
>>> the
>>> > current draft and let us know your thoughts:
>>> > https://www.python.org/dev/peps/pep-0646/ (Note that the final couple
>>> of
>>> > sections are out of date; https://github.com/python/peps/pull/1880
>>> > clarifies which grammar changes would be required, now that PEP 637 has
>>> > been rejected. We also have a second PR in progress at
>>> > https://github.com/python/peps/pull/1881 clarifying some of the
>>> motivation.)
>>> >
>>> > Thanks!
>>> > Matthew and Pradeep
>>>
>>> Hi,
>>> I'm very late to the discussion -- I relied on the typing-sig and SC to
>>> handle this, but now that I'm on the SC, I no longer have that luxury :)
>>> This mail has my own opinions, not necessarily the SC's.
>>>
>>>
>>> I've read the PEP, and I quite like it! It's clear that typing-sig
>>> thought this through very well.
>>> The thing that surprised me is the proposed changes that affect more
>>> than typing annotations. Quite deep in the PEP, the "Grammar Changes"
>>> section explains the (quite exciting) change to make star-unpacking
>>> possible in normal indexing operations, e.g.::
>>>
>>>  idxs_to_select = (1, 2)
>>>  array[0, *idxs_to_select, -1]  # Equivalent to [0, 1, 2, -1]
>>>
>>> However, the PEP is silent about indexing assignment, e.g.::
>>>
>>>  array[0, *idxs_to_select, -1] = 1
>>>
>>> IMO, it would be very confusing to not keep these in sync. If they are,
>>> the assignment change should be documented and tested appropriately. Is
>>> that the plan?
>>>
>>
>> The previous SC approved the PEP despite this.
>>
>> If you want to convince the SC to request this feature parity in the PEP,
>> I won't stop you.
>>
>> But unless that happens I would rather not upd