[Python-ideas] Re: Structure Pattern for annotation
I guess you could work around this by exploiting the slicing operator: GenericClass[:(A, B)] It makes sense to use the : in the context of typing, but I can see how this syntax can be confusing. The least confusing implementation I could think of is to limit the use of GenericClass[:_] to tuples, lists, sets and dicts (and future callable type signatures?), i.e.; it should only be used for structural type pattern matching. Here is a simple demo: https://gist.github.com/jorenham/1c241a1cf33d2cc8235631b63fa8f279 ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/JDBJGEPF2HVRJKZIWDU6CM5SW7ABDWZQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
El vie, 15 oct 2021 a las 14:42, Abdulla Al Kathiri (< alkathiri.abdu...@gmail.com>) escribió: > I don’t understand why tuple structure is not supported already. It makes > reading the function signature a breeze and very natural. You can also do > it without parentheses which mimics the return of multiple objects often > seen in functions(def func(*args: int) -> str, [int]) > > I brought this up before and one issue is that it's hard to distinguish between a tuple used as a type parameter and multiple type parameters: GenericClass[(A, B)] # parameterized by the type Tuple[A, B] GenericClass[A, B] # two type parameters The ASTs for both of those are the same, so it would be difficult for mypy to distinguish them. I do agree that it would be nice to write types like ([str], [int]), but there are some practical problems. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/BZBQFKZFBFE7VQZZ5FEMNYN3KJDZPNMF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
I don’t understand why tuple structure is not supported already. It makes reading the function signature a breeze and very natural. You can also do it without parentheses which mimics the return of multiple objects often seen in functions(def func(*args: int) -> str, [int]) > On 14 Oct 2021, at 12:53 PM, Alex Waygood wrote: > > I agree with Steven. I very much like Abdulla's proposed syntax for dicts, > TypedDicts and sets. But I'm not sure that the idea for `Annotated` is > workable, and the proposal for lists seems too prone to ambiguity, given how > extensively square brackets are already used in typing syntax. > > One question about the proposals, however: how would we represent other > mappings apart from dicts? Would `collections.abc.Mapping` and > `types.MappingProxyType` still be spelled as `Mapping[str, int]` and > `MappingProxyType[str, int]`? If so, that would be a slightly annoying > inconsistency. > > I do also quite like the idea of an improved syntax for tuples specifically. > Tuples are already very different types to lists/strings/etc in the context > of typing, essentially representing heterogeneous structs of fixed length > rather than homogenous sequences of unspecified length. As such, I think it > "makes sense" to special-case tuples without special-casing other sequences > such as list, `collections.abc.Sequence` or `collections.deque`. > > def foo() -> tuple[list[list[str]], list[list[str]]] > > would become > > def foo() -> (list[list[str]], list[list[str]]) > > That feels quite readable and natural, to me. > > Best, > Alex > >> On 14 Oct 2021, at 09:25, Steven D'Aprano wrote: >> >> On Thu, Oct 14, 2021 at 12:32:57AM +0400, Abdulla Al Kathiri wrote: >> >>> Today I found myself write a function that returns a tuple of list of >>> list of strings (tuple[list[list[str]], list[list[str]]]). Wouldn’t it >>> easier to read to write it like the following: >>> ([[str]], [[str]])? >> >> Not really. Your first example is explicit and I can get the meaning by >> just reading it out loud: >> >>tuple[list[list[str]], list[list[str]]] >> >>"tuple (of) list (of) list (of) str, list (of) list (of) str >> >> Your abbreviated version: >> >>([[str]], [[str]]) >> >> is too terse. I have to stop and think about what it means, not just >> read it out loud. Without the hint of named types (tuple and list), my >> first reaction to seeing [str] is "is this an optional string?". >> >> And then I wonder why it's not written: >> >>([[""]], [[""]]) >> >> Why abbreviate list and tuple but not string? >> >> Code is read more than it is written, and can be too terse as well as >> too verbose. >> >> On the other hand: >> >>> Similarly for TypedDict, replace the following.. >>> class Movie(TypedDict): >>>name: str >>>year: int >>> with >>> {‘name’: str, ‘year’: int} >> >> To my eye, that one does work. As far as I know, curly brackets {} >> aren't otherwise used in annotations (unlike square brackets), and they >> don't look like "optional" to me. They look like a dict. >> >> So on first glance at least, I think that: >> >>{'name': str, 'year': int} >> >> is better than the class syntax we already have. >> >> >> Likewise: >> >>> dict[str, int] will be {str: int} >>> set[int] will be {int}. >> >> work for me too. >> >> >>> Also, Annotated[float, “seconds”] can be replaced with something like >>> float #seconds indicating whatever comes after the hashtag is just >>> extra information similar to a normal comment in the code. >> >> No, because the # indicates that the rest of the line is a comment. This >> is already legal: >> >>def func(d: {str # this is an actual comment >> : int}) -> Any: ... >> >> so this would be ambiguous between a real comment and an annotation. >> >> Even if we agreed to change the behaviour of comments, you suggested: >> >>func(d: {str # product label: [float] # prices from 2000 to 2015}) >> >> How is the interpreter to know that the first annotation is just >> >>"product label" >> >> rather than this? >> >>"product label: [float] # prices from 2000 to 2015" >> >> So I don't think this works. >> >> >> -- >> Steve >> ___ >> Python-ideas mailing list -- python-ideas@python.org >> To unsubscribe send an email to python-ideas-le...@python.org >> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-ideas@python.org/message/T7E54DZW6EENRT373ZMCTU5WWRQ5M2TN/ >> Code of Conduct: http://python.org/psf/codeofconduct/ > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at >
[Python-ideas] Re: Structure Pattern for annotation
> On 14 Oct 2021, at 12:21 PM, Steven D'Aprano wrote: > > > Why abbreviate list and tuple but not string? > Empty strings would be confusing as a type unless you mean a Literal empty string. We just limit the picture of the type to lists, tuples, dicts, and sets. Builtin most often used collections. Imagine you have a default parameter like this... name: “” = “”. This adds unnecessary confusion. > Not really. Your first example is explicit and I can get the meaning by > just reading it out loud: > >tuple[list[list[str]], list[list[str]]] > >"tuple (of) list (of) list (of) str, list (of) list (of) str > > Your abbreviated version: > >([[str]], [[str]]) > > is too terse. I have to stop and think about what it means, not just > read it out loud. Without the hint of named types (tuple and list), my > first reaction to seeing [str] is "is this an optional string?". I am a visual guy. ([[str]], [[str]]) is much easier to my eyes than reading tuple (of) list (of) list (of) str, list (of) list (of) str. > don't look like "optional" to me Optional would be Optional[str] or str | None, not [str]. > No, because the # indicates that the rest of the line is a comment. This > is already legal: > >def func(d: {str # this is an actual comment > : int}) -> Any: ... > > so this would be ambiguous between a real comment and an annotation. > > Even if we agreed to change the behaviour of comments, you suggested: > >func(d: {str # product label: [float] # prices from 2000 to 2015}) > > How is the interpreter to know that the first annotation is just > >"product label" > > rather than this? > >"product label: [float] # prices from 2000 to 2015" > > So I don't think this works. > # is not a good idea I agree. How about the following for Annotated: func(d: {str & "product label": [float] & "prices from 2000 to 2015"})? The “&” is similar to “& co.” (and company). They come together but the first one is the group leader and represents all of them. It works in an opposite way to “|” (or), which gives importance equally to the members. def func( time: float & “hours” & datetime.timedelta.total_seconds()/3600, verbose: bool & “option for long text” = False, ) -> str: … Abdulla ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OGAMCS4GERWUM47AXHHYPZYGJHQDK7MK/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
On Fri, Oct 15, 2021 at 1:06 PM Finn Mason wrote: > I love the proposal for dicts, but I agree that this discourages duck > typing. Could the curly braces notation represent Mapping, not dict > specifically? > > +1 to shortening tuples but not other sequences. > > > -- > Finn Mason > That might be useful. But don't forget there is also MutableMapping. --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ICTEPGREJLEVCKYMQ6MYLKRCNZ7NO7SY/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
I love the proposal for dicts, but I agree that this discourages duck typing. Could the curly braces notation represent Mapping, not dict specifically? +1 to shortening tuples but not other sequences. -- Finn Mason On Thu, Oct 14, 2021, 6:46 AM Paul Moore wrote: > On Thu, 14 Oct 2021 at 13:04, Ricky Teachey wrote: > > > > I think all of this additional syntax is just a mistake. > > > > The reason is it will encourage people to not properly annotate their > input types for duck typing. Some of these shortcuts might be nice for > output types. But the more general trying.Mapping, typing.Sequence and > friends should be preferred for input types. If terse shortcuts are > available for the concrete data structure types, but not for the generic > types, a lot of people are going to feel nudged to type hint their python > improperly. > > +1. I'm not sure how much of my reservations about this whole > discussion are ultimately reservations about typing in general, but I > feel that the more we make it easier to express "exact" types, the > more we encourage people to constrain their APIs to take precise types > rather than to work with duck types. (I saw an example recently where > even Mapping was over-specified, all that was needed was __getitem__, > not even __len__ or __iter__). > > I know protocols allow duck typing in a static type checking context - > maybe the energy focused on "making basic types easier to write" > should be focused on making protocols easier to write, instead. > > Paul > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/KALBNJN2T4HAZFK4PZUV5RGAKXAVWCMD/ > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/C6HATFD4GXM73TDB6IMLBDIJPRVICIKI/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
On Thu, Oct 14, 2021 at 8:46 AM Paul Moore wrote: > > ...maybe the energy focused on "making basic types easier to write" > should be focused on making protocols easier to write, instead. > > Paul > + a billion Rick. --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FAKH72P57D3BZEH2BVUA5H27V63E5NCO/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
On Thu, 14 Oct 2021 at 13:04, Ricky Teachey wrote: > > I think all of this additional syntax is just a mistake. > > The reason is it will encourage people to not properly annotate their input > types for duck typing. Some of these shortcuts might be nice for output > types. But the more general trying.Mapping, typing.Sequence and friends > should be preferred for input types. If terse shortcuts are available for the > concrete data structure types, but not for the generic types, a lot of people > are going to feel nudged to type hint their python improperly. +1. I'm not sure how much of my reservations about this whole discussion are ultimately reservations about typing in general, but I feel that the more we make it easier to express "exact" types, the more we encourage people to constrain their APIs to take precise types rather than to work with duck types. (I saw an example recently where even Mapping was over-specified, all that was needed was __getitem__, not even __len__ or __iter__). I know protocols allow duck typing in a static type checking context - maybe the energy focused on "making basic types easier to write" should be focused on making protocols easier to write, instead. Paul ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/KALBNJN2T4HAZFK4PZUV5RGAKXAVWCMD/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
I agree with Steven. I very much like Abdulla's proposed syntax for dicts, TypedDicts and sets. But I'm not sure that the idea for `Annotated` is workable, and the proposal for lists seems too prone to ambiguity, given how extensively square brackets are already used in typing syntax. One question about the proposals, however: how would we represent other mappings apart from dicts? Would `collections.abc.Mapping` and `types.MappingProxyType` still be spelled as `Mapping[str, int]` and `MappingProxyType[str, int]`? If so, that would be a slightly annoying inconsistency. I do also quite like the idea of an improved syntax for tuples specifically. Tuples are already very different types to lists/strings/etc in the context of typing, essentially representing heterogeneous structs of fixed length rather than homogenous sequences of unspecified length. As such, I think it "makes sense" to special-case tuples without special-casing other sequences such as list, `collections.abc.Sequence` or `collections.deque`. def foo() -> tuple[list[list[str]], list[list[str]]] would become def foo() -> (list[list[str]], list[list[str]]) That feels quite readable and natural, to me. Best, Alex > On 14 Oct 2021, at 09:25, Steven D'Aprano wrote: > On Thu, Oct 14, 2021 at 12:32:57AM +0400, Abdulla Al Kathiri wrote: > >> Today I found myself write a function that returns a tuple of list of >> list of strings (tuple[list[list[str]], list[list[str]]]). Wouldn’t it >> easier to read to write it like the following: >> ([[str]], [[str]])? > > Not really. Your first example is explicit and I can get the meaning by > just reading it out loud: > >tuple[list[list[str]], list[list[str]]] > >"tuple (of) list (of) list (of) str, list (of) list (of) str > > Your abbreviated version: > >([[str]], [[str]]) > > is too terse. I have to stop and think about what it means, not just > read it out loud. Without the hint of named types (tuple and list), my > first reaction to seeing [str] is "is this an optional string?". > > And then I wonder why it's not written: > >([[""]], [[""]]) > > Why abbreviate list and tuple but not string? > > Code is read more than it is written, and can be too terse as well as > too verbose. > > On the other hand: > >> Similarly for TypedDict, replace the following.. >> class Movie(TypedDict): >>name: str >>year: int >> with >> {‘name’: str, ‘year’: int} > > To my eye, that one does work. As far as I know, curly brackets {} > aren't otherwise used in annotations (unlike square brackets), and they > don't look like "optional" to me. They look like a dict. > > So on first glance at least, I think that: > >{'name': str, 'year': int} > > is better than the class syntax we already have. > > > Likewise: > >> dict[str, int] will be {str: int} >> set[int] will be {int}. > > work for me too. > > >> Also, Annotated[float, “seconds”] can be replaced with something like >> float #seconds indicating whatever comes after the hashtag is just >> extra information similar to a normal comment in the code. > > No, because the # indicates that the rest of the line is a comment. This > is already legal: > >def func(d: {str # this is an actual comment > : int}) -> Any: ... > > so this would be ambiguous between a real comment and an annotation. > > Even if we agreed to change the behaviour of comments, you suggested: > >func(d: {str # product label: [float] # prices from 2000 to 2015}) > > How is the interpreter to know that the first annotation is just > >"product label" > > rather than this? > >"product label: [float] # prices from 2000 to 2015" > > So I don't think this works. > > > -- > Steve > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/T7E54DZW6EENRT373ZMCTU5WWRQ5M2TN/ > Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YUPJNZVGYDANDHFD5VI54GRRNLGUAFBP/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
On Thu, Oct 14, 2021 at 12:32:57AM +0400, Abdulla Al Kathiri wrote: > Today I found myself write a function that returns a tuple of list of > list of strings (tuple[list[list[str]], list[list[str]]]). Wouldn’t it > easier to read to write it like the following: > ([[str]], [[str]])? Not really. Your first example is explicit and I can get the meaning by just reading it out loud: tuple[list[list[str]], list[list[str]]] "tuple (of) list (of) list (of) str, list (of) list (of) str Your abbreviated version: ([[str]], [[str]]) is too terse. I have to stop and think about what it means, not just read it out loud. Without the hint of named types (tuple and list), my first reaction to seeing [str] is "is this an optional string?". And then I wonder why it's not written: ([[""]], [[""]]) Why abbreviate list and tuple but not string? Code is read more than it is written, and can be too terse as well as too verbose. On the other hand: > Similarly for TypedDict, replace the following.. > class Movie(TypedDict): > name: str > year: int > with > {‘name’: str, ‘year’: int} To my eye, that one does work. As far as I know, curly brackets {} aren't otherwise used in annotations (unlike square brackets), and they don't look like "optional" to me. They look like a dict. So on first glance at least, I think that: {'name': str, 'year': int} is better than the class syntax we already have. Likewise: > dict[str, int] will be {str: int} > set[int] will be {int}. work for me too. > Also, Annotated[float, “seconds”] can be replaced with something like > float #seconds indicating whatever comes after the hashtag is just > extra information similar to a normal comment in the code. No, because the # indicates that the rest of the line is a comment. This is already legal: def func(d: {str # this is an actual comment : int}) -> Any: ... so this would be ambiguous between a real comment and an annotation. Even if we agreed to change the behaviour of comments, you suggested: func(d: {str # product label: [float] # prices from 2000 to 2015}) How is the interpreter to know that the first annotation is just "product label" rather than this? "product label: [float] # prices from 2000 to 2015" So I don't think this works. -- Steve ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T7E54DZW6EENRT373ZMCTU5WWRQ5M2TN/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Structure Pattern for annotation
I find myself using exactly that "picture of the data" approach informally for code I don't plan on formally type checking (but want to show intent). E.g. def myfun(data: {str: [CustomType]}) -> [(int, OtherType)]: ... Maybe it's a bad habit, but it feels easier to parse visually than the real `typing.py` stuff. On Wed, Oct 13, 2021, 4:35 PM Abdulla Al Kathiri < alkathiri.abdu...@gmail.com> wrote: > Hello, > > Today I found myself write a function that returns a tuple of list of list > of strings (tuple[list[list[str]], list[list[str]]]). Wouldn’t it easier to > read to write it like the following: > ([[str]], [[str]])? > Similarly for TypedDict, replace the following.. > > class Movie(TypedDict): > name: str > year: int > > with > {‘name’: str, ‘year’: int} > dict[str, int] will be {str: int} > set[int] will be {int}. > This is similar to the new proposed Callable alternative (i.e., (int, > float) -> float) since it mimics the structure of a function. > > Also, Annotated[float, “seconds”] can be replaced with something like > float #seconds indicating whatever comes after the hashtag is just extra > information similar to a normal comment in the code. > Imagine you could replace the following > def func(d: dict[Annotated[str, “product label”], Annotated[list[float], > “prices from 2000 to 2015”]])… > With > def func(d: {str # product label: [float] # prices from 2000 to 2015})… > Abdulla > Sent from my iPhone > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/D6LHXDXPN6K27KV6MZBLG66ZSGCNDRG7/ > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HYBIYHKE4ZAKTV33VB4AE37MG576KYH5/ Code of Conduct: http://python.org/psf/codeofconduct/