typing: how to use names in result-tuples?
Hi friends, I am meanwhile the PySide maintainer at The Qt Company, and we are trying to make the mapping from Qt functions to Python functions as comparable as possible. One problem are primitive pointer variables: In Qt, it is natural to use "sometype *varname" to make a mutable variable. In Python, you have to turn such a thing into a result-tuple. Example: void QPrinter::getPageMargins(qreal *left, qreal *top, \ qreal *right, qreal *bottom, QPrinter::Unit unit) const (meanwhile deprecated, but a good example) is mapped to the Python signature def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.Tuple[float, float, float, float]: ... NOW my question: ---------------- I would like to retain the variable names in Python! The first idea is to use typing.NamedTuple, but I get the impression that this would be too much, because I would not only need to create an extra named tuple definition for every set of names, but also invent a name for that named tuple. What I would like to have is something that looks like def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.NamedTuple[left: float, top: float, \ right:float, bottom:float]: ... but that is obviously not a named tuple. Possible would be to derive a name from the function, so maybe a definition could be used like class PageMargingResult(NamedTuple): left: float top: float right: float bottom: float but then I would have some opaque PageMargingResult type. This would work, but as said, this is a bit too much, since I only wanted something like a tuple with names. What do you suggest to do here? Something what I am missing? Cheers -- Chris -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
Can't you use the proper inline form of NamedTuple? def f() -> typing.NamedTuple("__f", [("x", int), ("y", int)]): ... seems to work. On Mon, Jul 29, 2019 at 8:26 AM Christian Tismer <tismer@stackless.com> wrote:
Hi friends,
I am meanwhile the PySide maintainer at The Qt Company, and we are trying to make the mapping from Qt functions to Python functions as comparable as possible.
One problem are primitive pointer variables: In Qt, it is natural to use "sometype *varname" to make a mutable variable. In Python, you have to turn such a thing into a result-tuple. Example:
void QPrinter::getPageMargins(qreal *left, qreal *top, \ qreal *right, qreal *bottom, QPrinter::Unit unit) const
(meanwhile deprecated, but a good example)
is mapped to the Python signature
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.Tuple[float, float, float, float]: ...
NOW my question: ----------------
I would like to retain the variable names in Python! The first idea is to use typing.NamedTuple, but I get the impression that this would be too much, because I would not only need to create an extra named tuple definition for every set of names, but also invent a name for that named tuple.
What I would like to have is something that looks like
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.NamedTuple[left: float, top: float, \ right:float, bottom:float]: ...
but that is obviously not a named tuple. Possible would be to derive a name from the function, so maybe a definition could be used like
class PageMargingResult(NamedTuple): left: float top: float right: float bottom: float
but then I would have some opaque PageMargingResult type. This would work, but as said, this is a bit too much, since I only wanted something like a tuple with names.
What do you suggest to do here? Something what I am missing?
Cheers -- Chris -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/YGZELVWR...
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Yes, maybe I can use that. With Python >= 3.6, also def f() -> typing.NamedTuple("__f", x=int, y=int): ... which is concise, but a slightly weird abuse. But there are other drawbacks:
typing.Tuple[int, int] typing.Tuple[int, int] typing.Tuple[int, int] is typing.Tuple[int, int] True
versus
typing.NamedTuple("__f", x=int, y=int) <class '__main__.__f'> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", x=int, y=int) False
I think the whole NameTuple implementation looks a bit half-hearted, so I was looking to find something that is closer to the perfect behavior of the other typing types. Maybe I should try to implement something that keeps proper identity like Tuple and avoids the useless function name? Like def f() -> typing.KwTuple(x=int, y=int): ... or def f() -> typing.KwTuple([("x", int), ("y", int)]): ... cheers -- Chris On 29.07.19 18:00, Guido van Rossum wrote:
Can't you use the proper inline form of NamedTuple?
def f() -> typing.NamedTuple("__f", [("x", int), ("y", int)]): ...
seems to work.
On Mon, Jul 29, 2019 at 8:26 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi friends,
I am meanwhile the PySide maintainer at The Qt Company, and we are trying to make the mapping from Qt functions to Python functions as comparable as possible.
One problem are primitive pointer variables: In Qt, it is natural to use "sometype *varname" to make a mutable variable. In Python, you have to turn such a thing into a result-tuple. Example:
void QPrinter::getPageMargins(qreal *left, qreal *top, \ qreal *right, qreal *bottom, QPrinter::Unit unit) const
(meanwhile deprecated, but a good example)
is mapped to the Python signature
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.Tuple[float, float, float, float]: ...
NOW my question: ----------------
I would like to retain the variable names in Python! The first idea is to use typing.NamedTuple, but I get the impression that this would be too much, because I would not only need to create an extra named tuple definition for every set of names, but also invent a name for that named tuple.
What I would like to have is something that looks like
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.NamedTuple[left: float, top: float, \ right:float, bottom:float]: ...
but that is obviously not a named tuple. Possible would be to derive a name from the function, so maybe a definition could be used like
class PageMargingResult(NamedTuple): left: float top: float right: float bottom: float
but then I would have some opaque PageMargingResult type. This would work, but as said, this is a bit too much, since I only wanted something like a tuple with names.
What do you suggest to do here? Something what I am missing?
Cheers -- Chris -- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
_______________________________________________ Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/YGZELVWR...
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/LSNP3DUX...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com> wrote:
typing.NamedTuple("__f", x=int, y=int) <class '__main__.__f'> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", x=int, y=int) False
This appears to go right back to collections.namedtuple:
from collections import namedtuple n1 = namedtuple('f', ['a', 'b', 'c']) n2 = namedtuple('f', ['a', 'b', 'c']) n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
from functools import lru_cache cached_namedtuple = lru_cache(None)(namedtuple) n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable n2 = cached_namedtuple('f', ('a', 'b', 'c')) n1 is n2 True
Paul
I think I have to agree with Petr. Define explicit type names. On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com> wrote:
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com> wrote:
typing.NamedTuple("__f", x=int, y=int) <class '__main__.__f'> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", x=int, y=int) False
This appears to go right back to collections.namedtuple:
from collections import namedtuple n1 = namedtuple('f', ['a', 'b', 'c']) n2 = namedtuple('f', ['a', 'b', 'c']) n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
from functools import lru_cache cached_namedtuple = lru_cache(None)(namedtuple) n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable n2 = cached_namedtuple('f', ('a', 'b', 'c')) n1 is n2 True
Paul
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Hi all, Ok, I am about to implement generation of such structures automatically using the struct sequence concept. One more question: ------------------ Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types. * namedtuple has made the transition to NamedTuple * What would I need to do that for StructSequence as well? Things get also a bit more complicated since struct sequence objects can contain unnamed fields. Any advice would be appreciated, I am no typing expert (yet :-) cheers -- Chris On 30.07.19 17:10, Guido van Rossum wrote:
I think I have to agree with Petr. Define explicit type names.
On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>> wrote:
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote: > >>> typing.NamedTuple("__f", x=int, y=int) > <class '__main__.__f'> > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > x=int, y=int) > False
This appears to go right back to collections.namedtuple:
>>> from collections import namedtuple >>> n1 = namedtuple('f', ['a', 'b', 'c']) >>> n2 = namedtuple('f', ['a', 'b', 'c']) >>> n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
>>> from functools import lru_cache >>> cached_namedtuple = lru_cache(None)(namedtuple) >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) >>> n1 is n2 True
Paul
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/GIFRTFWP...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
Alas, we didn't think of struct sequences when we designed PEP 484. It seems they are a hybrid of Tuple and NamedTuple; both of these are currently special-cased in mypy in ways that cannot easily be combined. Do you really need anonymous fields? I see an example in typeshed/stdlib/3/os/__init__.pyi (in github.com/python/typeshed), for stat_result. It defines names for all the fields, plus a __getitem__() method that indicates that indexing returns an int. This doesn't help if anonymous fields could have different types, not does it teach the type checker about the number of anonymous fields. --Guido On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com> wrote:
Hi all,
Ok, I am about to implement generation of such structures automatically using the struct sequence concept.
One more question: ------------------
Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types.
* namedtuple has made the transition to NamedTuple
* What would I need to do that for StructSequence as well?
Things get also a bit more complicated since struct sequence objects can contain unnamed fields.
Any advice would be appreciated, I am no typing expert (yet :-)
cheers -- Chris
On 30.07.19 17:10, Guido van Rossum wrote:
I think I have to agree with Petr. Define explicit type names.
On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>> wrote:
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote: > >>> typing.NamedTuple("__f", x=int, y=int) > <class '__main__.__f'> > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > x=int, y=int) > False
This appears to go right back to collections.namedtuple:
>>> from collections import namedtuple >>> n1 = namedtuple('f', ['a', 'b', 'c']) >>> n2 = namedtuple('f', ['a', 'b', 'c']) >>> n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
>>> from functools import lru_cache >>> cached_namedtuple = lru_cache(None)(namedtuple) >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) >>> n1 is n2 True
Paul
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ < http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/GIFRTFWP...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Hi Guido, If a C++ function already has a return value, plus some primitive pointer variables that need to be moved into the result in Python, then we have the case with a first, single unnamed field. Only one such field can exist. I'm not sure if that case exists in the ~25000 Qt5 functions, but in that case, I think to give that single field the name "unnamed" or maybe better "result". Thank you very much for pointing me to that example! Cheers -- Chris On 08.08.19 06:41, Guido van Rossum wrote:
Alas, we didn't think of struct sequences when we designed PEP 484. It seems they are a hybrid of Tuple and NamedTuple; both of these are currently special-cased in mypy in ways that cannot easily be combined.
Do you really need anonymous fields?
I see an example in typeshed/stdlib/3/os/__init__.pyi (in github.com/python/typeshed <http://github.com/python/typeshed>), for stat_result. It defines names for all the fields, plus a __getitem__() method that indicates that indexing returns an int. This doesn't help if anonymous fields could have different types, not does it teach the type checker about the number of anonymous fields.
--Guido
On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi all,
Ok, I am about to implement generation of such structures automatically using the struct sequence concept.
One more question: ------------------
Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types.
* namedtuple has made the transition to NamedTuple
* What would I need to do that for StructSequence as well?
Things get also a bit more complicated since struct sequence objects can contain unnamed fields.
Any advice would be appreciated, I am no typing expert (yet :-)
cheers -- Chris
On 30.07.19 17:10, Guido van Rossum wrote: > I think I have to agree with Petr. Define explicit type names. > > On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> > <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>>> wrote: > > On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> > <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>> wrote: > > >>> typing.NamedTuple("__f", x=int, y=int) > > <class '__main__.__f'> > > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > > x=int, y=int) > > False > > This appears to go right back to collections.namedtuple: > > >>> from collections import namedtuple > >>> n1 = namedtuple('f', ['a', 'b', 'c']) > >>> n2 = namedtuple('f', ['a', 'b', 'c']) > >>> n1 is n2 > False > > I found that surprising, as I expected the named tuple type to be > cached based on the declared name 'f'. But it's been that way forever > so obviously my intuition here is wrong. But maybe it would be useful > for this case if there *was* a way to base named tuple identity off > the name/fields? It could be as simple as caching the results: > > >>> from functools import lru_cache > >>> cached_namedtuple = lru_cache(None)(namedtuple) > >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather > than a list of field names, as lists aren't hashable > >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) > >>> n1 is n2 > True > > Paul > > > > -- > --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido>) > /Pronouns: he/him/his //(why is my pronoun here?)/ > <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> > > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> > To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/GIFRTFWP... >
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/QZ44KHLL...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
Chrisian, How would these namedtuple/structseq values be used? I have a similar design with PyObjC: pass-by-reference “return” values are returned in a tuple, e.g.: void getpoint(pointclass* v, int* x, int *y) => def get point(v: pointless) -> (int, int) BOOL getvalue(someclass* v, int* val) => def getvalue(v: someclass) -> (bool, int) I rarely, if ever, see code that actually stores the return tuple as-is. The return tuple is just deconstructed immediately, like “x, y = getpoint(mypoint)”. Ronald — Twitter: @ronaldoussoren Blog: https://blog.ronaldoussoren.net/
On 8 Aug 2019, at 10:42, Christian Tismer <tismer@stackless.com> wrote:
Hi Guido,
If a C++ function already has a return value, plus some primitive pointer variables that need to be moved into the result in Python, then we have the case with a first, single unnamed field. Only one such field can exist.
I'm not sure if that case exists in the ~25000 Qt5 functions, but in that case, I think to give that single field the name "unnamed" or maybe better "result".
Thank you very much for pointing me to that example!
Cheers -- Chris
On 08.08.19 06:41, Guido van Rossum wrote:
Alas, we didn't think of struct sequences when we designed PEP 484. It seems they are a hybrid of Tuple and NamedTuple; both of these are currently special-cased in mypy in ways that cannot easily be combined.
Do you really need anonymous fields?
I see an example in typeshed/stdlib/3/os/__init__.pyi (in github.com/python/typeshed <http://github.com/python/typeshed>), for stat_result. It defines names for all the fields, plus a __getitem__() method that indicates that indexing returns an int. This doesn't help if anonymous fields could have different types, not does it teach the type checker about the number of anonymous fields.
--Guido
On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi all,
Ok, I am about to implement generation of such structures automatically using the struct sequence concept.
One more question: ------------------
Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types.
* namedtuple has made the transition to NamedTuple
* What would I need to do that for StructSequence as well?
Things get also a bit more complicated since struct sequence objects can contain unnamed fields.
Any advice would be appreciated, I am no typing expert (yet :-)
cheers -- Chris
On 30.07.19 17:10, Guido van Rossum wrote:
I think I have to agree with Petr. Define explicit type names.
On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>>> wrote:
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>> wrote: > >>> typing.NamedTuple("__f", x=int, y=int) > <class '__main__.__f'> > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > x=int, y=int) > False
This appears to go right back to collections.namedtuple:
>>> from collections import namedtuple >>> n1 = namedtuple('f', ['a', 'b', 'c']) >>> n2 = namedtuple('f', ['a', 'b', 'c']) >>> n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
>>> from functools import lru_cache >>> cached_namedtuple = lru_cache(None)(namedtuple) >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) >>> n1 is n2 True
Paul
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org
<mailto:python-dev@python.org>
To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/GIFRTFWP...
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/QZ44KHLL...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023 _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/I4LGR6Q6...
Hi Ronald, sure, the tuple is usually not very interesting; people look it up once and use that info in the code. But I think things can be made quite efficient and pretty at the same time. Such a return tuple could be hidden like the stat_result example that Guido mentioned: https://github.com/python/typeshed/blob/master/stdlib/3/os/__init__.pyi def stat(self, *, follow_symlinks: bool = ...) -> stat_result: ... The stat_result is a huge structure where you don't want to see much unless you are working with a stat_result. Other with common, repeating patterns like (x, y, width, height) or your examples: def getpoint(v: pointless) -> (int, int) def getvalue(v: someclass) -> (bool, int) would be at first sight def getpoint(v: pointless) -> getpoint_result def getvalue(v: someclass) -> getvalue_result But actually, a much nicer, speaking outcome would be written as the single function StructSequence(...) with arguments, producing: def getpoint(v: pointless) -> StructSequence(x=int, y=int) def getvalue(v: someclass) -> StructSequence(result=bool, val=int) That would have the nice effect of a very visible structure in the .pyi file. When you actually get such an object and look at it, then you have
getpoint(pointless()) getpoint_result(x=17, y=4) getvalue(someclass()) getvalue_result(result=True, val=42))
And the "magic" function StructSequence would simply index a dict with the given argument tuple that gives the right struct sequence. This is always possible, since only names and types are involved in the lookup. Cheers -- Chris On 08.08.19 14:22, Ronald Oussoren wrote:
Chrisian,
How would these namedtuple/structseq values be used? I have a similar design with PyObjC: pass-by-reference “return” values are returned in a tuple, e.g.:
void getpoint(pointclass* v, int* x, int *y) => def get point(v: pointless) -> (int, int) BOOL getvalue(someclass* v, int* val) => def getvalue(v: someclass) -> (bool, int)
I rarely, if ever, see code that actually stores the return tuple as-is. The return tuple is just deconstructed immediately, like “x, y = getpoint(mypoint)”.
Ronald —
Twitter: @ronaldoussoren Blog: https://blog.ronaldoussoren.net/
On 8 Aug 2019, at 10:42, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi Guido,
If a C++ function already has a return value, plus some primitive pointer variables that need to be moved into the result in Python, then we have the case with a first, single unnamed field. Only one such field can exist.
I'm not sure if that case exists in the ~25000 Qt5 functions, but in that case, I think to give that single field the name "unnamed" or maybe better "result".
Thank you very much for pointing me to that example!
Cheers -- Chris
On 08.08.19 06:41, Guido van Rossum wrote:
Alas, we didn't think of struct sequences when we designed PEP 484. It seems they are a hybrid of Tuple and NamedTuple; both of these are currently special-cased in mypy in ways that cannot easily be combined.
Do you really need anonymous fields?
I see an example in typeshed/stdlib/3/os/__init__.pyi (in github.com/python/typeshed <http://github.com/python/typeshed> <http://github.com/python/typeshed>), for stat_result. It defines names for all the fields, plus a __getitem__() method that indicates that indexing returns an int. This doesn't help if anonymous fields could have different types, not does it teach the type checker about the number of anonymous fields.
--Guido
On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com>> wrote:
Hi all,
Ok, I am about to implement generation of such structures automatically using the struct sequence concept.
One more question: ------------------
Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types.
* namedtuple has made the transition to NamedTuple
* What would I need to do that for StructSequence as well?
Things get also a bit more complicated since struct sequence objects can contain unnamed fields.
Any advice would be appreciated, I am no typing expert (yet :-)
cheers -- Chris
On 30.07.19 17:10, Guido van Rossum wrote:
I think I have to agree with Petr. Define explicit type names.
On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> <mailto:p.f.moore@gmail.com> <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>>> wrote:
On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com> <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>> wrote: > >>> typing.NamedTuple("__f", x=int, y=int) > <class '__main__.__f'> > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > x=int, y=int) > False
This appears to go right back to collections.namedtuple:
>>> from collections import namedtuple >>> n1 = namedtuple('f', ['a', 'b', 'c']) >>> n2 = namedtuple('f', ['a', 'b', 'c']) >>> n1 is n2 False
I found that surprising, as I expected the named tuple type to be cached based on the declared name 'f'. But it's been that way forever so obviously my intuition here is wrong. But maybe it would be useful for this case if there *was* a way to base named tuple identity off the name/fields? It could be as simple as caching the results:
>>> from functools import lru_cache >>> cached_namedtuple = lru_cache(None)(namedtuple) >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather than a list of field names, as lists aren't hashable >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) >>> n1 is n2 True
Paul
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido> <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org>
<mailto:python-dev@python.org>
To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@python.org> <mailto:python-dev-leave@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/GIFRTFWP...
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/QZ44KHLL...
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023 _______________________________________________ Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/I4LGR6Q6...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On 8 Aug 2019, at 17:12, Christian Tismer <tismer@stackless.com> wrote:
Hi Ronald,
sure, the tuple is usually not very interesting; people look it up once and use that info in the code.
But I think things can be made quite efficient and pretty at the same time. Such a return tuple could be hidden like the stat_result example that Guido mentioned:
https://github.com/python/typeshed/blob/master/stdlib/3/os/__init__.pyi <https://github.com/python/typeshed/blob/master/stdlib/3/os/__init__.pyi>
def stat(self, *, follow_symlinks: bool = ...) -> stat_result: ...
The stat_result is a huge structure where you don't want to see much unless you are working with a stat_result.
Other with common, repeating patterns like (x, y, width, height) or your examples:
def getpoint(v: pointless) -> (int, int) def getvalue(v: someclass) -> (bool, int)
would be at first sight
def getpoint(v: pointless) -> getpoint_result def getvalue(v: someclass) -> getvalue_result
But actually, a much nicer, speaking outcome would be written as the single function StructSequence(...) with arguments, producing:
def getpoint(v: pointless) -> StructSequence(x=int, y=int) def getvalue(v: someclass) -> StructSequence(result=bool, val=int)
That would have the nice effect of a very visible structure in the .pyi file. When you actually get such an object and look at it, then you have
But will you ever look at these objects, other then when exploring APIs in the REPL? As I wrote earlier the normal usage for a similar pattern in PyObjC is to always immediately deconstruct the tuple into its separate values. BTW. I’m primarily trying to understand your use case because it is so similar to what I’m doing in PyObjC, and such understanding can lead to an improvement in PyObjC ;-). Ronald
On 08.08.19 17:20, Ronald Oussoren via Python-Dev wrote:
On 8 Aug 2019, at 17:12, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi Ronald,
sure, the tuple is usually not very interesting; people look it up once and use that info in the code.
But I think things can be made quite efficient and pretty at the same time. Such a return tuple could be hidden like the stat_result example that Guido mentioned:
https://github.com/python/typeshed/blob/master/stdlib/3/os/__init__.pyi
def stat(self, *, follow_symlinks: bool = ...) -> stat_result: ...
The stat_result is a huge structure where you don't want to see much unless you are working with a stat_result.
Other with common, repeating patterns like (x, y, width, height) or your examples:
def getpoint(v: pointless) -> (int, int) def getvalue(v: someclass) -> (bool, int)
would be at first sight
def getpoint(v: pointless) -> getpoint_result def getvalue(v: someclass) -> getvalue_result
But actually, a much nicer, speaking outcome would be written as the single function StructSequence(...) with arguments, producing:
def getpoint(v: pointless) -> StructSequence(x=int, y=int) def getvalue(v: someclass) -> StructSequence(result=bool, val=int)
That would have the nice effect of a very visible structure in the .pyi file. When you actually get such an object and look at it, then you have
But will you ever look at these objects, other then when exploring APIs in the REPL? As I wrote earlier the normal usage for a similar pattern in PyObjC is to always immediately deconstruct the tuple into its separate values.
Yes, it is for exploring the interface. In Qt5, you have *very* many functions, and they are pretty unpythonic as well. That was the reason at all for me to write that __signature__ module for PySide, that does everything with introspection. When I'm programming with it, then half as a user who wants to see "yes, it really returns such a value" and as a developer "shit, we claim that interface, but lied". In a sense, it was also a way to test this huge library automatically, and I enjoy it when things can explain themselves. That is absolutely not necessary. As the whole typing idea and typeshed is not necessary, but for me it was a huge win to have a typed interface, and IDE users seem to love it when PyCharm suddenly talks to them ;-)
BTW. I’m primarily trying to understand your use case because it is so similar to what I’m doing in PyObjC, and such understanding can lead to an improvement in PyObjC ;-).
I am happy to learn from your projects as well! All the best -- Chris -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On 8 Aug 2019, at 17:42, Christian Tismer <tismer@stackless.com> wrote:
On 08.08.19 17:20, Ronald Oussoren via Python-Dev wrote:
On 8 Aug 2019, at 17:12, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi Ronald,
sure, the tuple is usually not very interesting; people look it up once and use that info in the code.
But I think things can be made quite efficient and pretty at the same time. Such a return tuple could be hidden like the stat_result example that Guido mentioned:
https://github.com/python/typeshed/blob/master/stdlib/3/os/__init__.pyi
def stat(self, *, follow_symlinks: bool = ...) -> stat_result: ...
The stat_result is a huge structure where you don't want to see much unless you are working with a stat_result.
Other with common, repeating patterns like (x, y, width, height) or your examples:
def getpoint(v: pointless) -> (int, int) def getvalue(v: someclass) -> (bool, int)
would be at first sight
def getpoint(v: pointless) -> getpoint_result def getvalue(v: someclass) -> getvalue_result
But actually, a much nicer, speaking outcome would be written as the single function StructSequence(...) with arguments, producing:
def getpoint(v: pointless) -> StructSequence(x=int, y=int) def getvalue(v: someclass) -> StructSequence(result=bool, val=int)
That would have the nice effect of a very visible structure in the .pyi file. When you actually get such an object and look at it, then you have
But will you ever look at these objects, other then when exploring APIs in the REPL? As I wrote earlier the normal usage for a similar pattern in PyObjC is to always immediately deconstruct the tuple into its separate values.
Yes, it is for exploring the interface. In Qt5, you have *very* many functions, and they are pretty unpythonic as well.
You haven’t seen the interfaces generated by PyObjC, compared to the PyQt interfaces are pretty pythonic :-).
That was the reason at all for me to write that __signature__ module for PySide, that does everything with introspection.
When I'm programming with it, then half as a user who wants to see "yes, it really returns such a value" and as a developer "shit, we claim that interface, but lied".
In a sense, it was also a way to test this huge library automatically, and I enjoy it when things can explain themselves. That is absolutely not necessary.
As the whole typing idea and typeshed is not necessary, but for me it was a huge win to have a typed interface, and IDE users seem to love it when PyCharm suddenly talks to them ;-)
I like the idea, even if it is just used for introspection and interactive use. I’m definitely adding exploring this for PyObjC to my list. Ronald — Twitter: @ronaldoussoren Blog: https://blog.ronaldoussoren.net/
OK, yes, having a convention for naming the anonymous field sounds like the way to go. But presuming people will want to use it, and probably know it from the C++ API, why not name it 'return_value' or 'result' or 'retval' or something like that? On Thu, Aug 8, 2019 at 1:43 AM Christian Tismer <tismer@stackless.com> wrote:
Hi Guido,
If a C++ function already has a return value, plus some primitive pointer variables that need to be moved into the result in Python, then we have the case with a first, single unnamed field. Only one such field can exist.
I'm not sure if that case exists in the ~25000 Qt5 functions, but in that case, I think to give that single field the name "unnamed" or maybe better "result".
Thank you very much for pointing me to that example!
Cheers -- Chris
On 08.08.19 06:41, Guido van Rossum wrote:
Alas, we didn't think of struct sequences when we designed PEP 484. It seems they are a hybrid of Tuple and NamedTuple; both of these are currently special-cased in mypy in ways that cannot easily be combined.
Do you really need anonymous fields?
I see an example in typeshed/stdlib/3/os/__init__.pyi (in github.com/python/typeshed <http://github.com/python/typeshed>), for stat_result. It defines names for all the fields, plus a __getitem__() method that indicates that indexing returns an int. This doesn't help if anonymous fields could have different types, not does it teach the type checker about the number of anonymous fields.
--Guido
On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi all,
Ok, I am about to implement generation of such structures automatically using the struct sequence concept.
One more question: ------------------
Struct sequences are not yet members of the typing types. I would like to add that, because a major use case is also to show nice .pyi files with all the functions and types.
* namedtuple has made the transition to NamedTuple
* What would I need to do that for StructSequence as well?
Things get also a bit more complicated since struct sequence objects can contain unnamed fields.
Any advice would be appreciated, I am no typing expert (yet :-)
cheers -- Chris
On 30.07.19 17:10, Guido van Rossum wrote: > I think I have to agree with Petr. Define explicit type names. > > On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> > <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>>> wrote: > > On Tue, 30 Jul 2019 at 09:33, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> > <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>> wrote: > > >>> typing.NamedTuple("__f", x=int, y=int) > > <class '__main__.__f'> > > >>> typing.NamedTuple("__f", x=int, y=int) is typing.NamedTuple("__f", > > x=int, y=int) > > False > > This appears to go right back to collections.namedtuple: > > >>> from collections import namedtuple > >>> n1 = namedtuple('f', ['a', 'b', 'c']) > >>> n2 = namedtuple('f', ['a', 'b', 'c']) > >>> n1 is n2 > False > > I found that surprising, as I expected the named tuple type to be > cached based on the declared name 'f'. But it's been that way forever > so obviously my intuition here is wrong. But maybe it would be useful > for this case if there *was* a way to base named tuple identity off > the name/fields? It could be as simple as caching the results: > > >>> from functools import lru_cache > >>> cached_namedtuple = lru_cache(None)(namedtuple) > >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather > than a list of field names, as lists aren't hashable > >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) > >>> n1 is n2 > True > > Paul > > > > -- > --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido>) > /Pronouns: he/him/his //(why is my pronoun here?)/ > < http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...
> > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> > To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/GIFRTFWP...
>
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <
http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/QZ44KHLL...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Yes, that's what I mean. Probably retval or whatever people prefer would be adequate, with a special rule if that name is taken. I think btw. that using StructSequence(somename=sometype, ..., ) that does a dict lookup is quite appealing. It returns a class like stat_result, but the function call shows its arguments (see answer to Ronald). Ciao -- Chris On 08.08.19 17:22, Guido van Rossum wrote:
OK, yes, having a convention for naming the anonymous field sounds like the way to go. But presuming people will want to use it, and probably know it from the C++ API, why not name it 'return_value' or 'result' or 'retval' or something like that?
On Thu, Aug 8, 2019 at 1:43 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Hi Guido,
If a C++ function already has a return value, plus some primitive pointer variables that need to be moved into the result in Python, then we have the case with a first, single unnamed field. Only one such field can exist.
I'm not sure if that case exists in the ~25000 Qt5 functions, but in that case, I think to give that single field the name "unnamed" or maybe better "result".
Thank you very much for pointing me to that example!
Cheers -- Chris
On 08.08.19 06:41, Guido van Rossum wrote: > Alas, we didn't think of struct sequences when we designed PEP 484. It > seems they are a hybrid of Tuple and NamedTuple; both of these are > currently special-cased in mypy in ways that cannot easily be combined. > > Do you really need anonymous fields? > > I see an example in typeshed/stdlib/3/os/__init__.pyi (in > github.com/python/typeshed <http://github.com/python/typeshed> <http://github.com/python/typeshed>), for > stat_result. It defines names for all the fields, plus a __getitem__() > method that indicates that indexing returns an int. This doesn't help if > anonymous fields could have different types, not does it teach the type > checker about the number of anonymous fields. > > --Guido > > On Wed, Aug 7, 2019 at 1:51 AM Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com> > <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>> wrote: > > Hi all, > > Ok, I am about to implement generation of such structures > automatically using the struct sequence concept. > > > One more question: > ------------------ > > Struct sequences are not yet members of the typing types. > I would like to add that, because a major use case is also to > show nice .pyi files with all the functions and types. > > * namedtuple has made the transition to NamedTuple > > * What would I need to do that for StructSequence as well? > > Things get also a bit more complicated since struct sequence > objects can contain unnamed fields. > > Any advice would be appreciated, I am no typing expert (yet :-) > > cheers -- Chris > > > On 30.07.19 17:10, Guido van Rossum wrote: > > I think I have to agree with Petr. Define explicit type names. > > > > On Tue, Jul 30, 2019 at 2:45 AM Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> > <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>> > > <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com> <mailto:p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>>>> wrote: > > > > On Tue, 30 Jul 2019 at 09:33, Christian Tismer > <tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com <mailto:tismer@stackless.com>> > > <mailto:tismer@stackless.com <mailto:tismer@stackless.com> <mailto:tismer@stackless.com <mailto:tismer@stackless.com>>>> > wrote: > > > >>> typing.NamedTuple("__f", x=int, y=int) > > > <class '__main__.__f'> > > > >>> typing.NamedTuple("__f", x=int, y=int) is > typing.NamedTuple("__f", > > > x=int, y=int) > > > False > > > > This appears to go right back to collections.namedtuple: > > > > >>> from collections import namedtuple > > >>> n1 = namedtuple('f', ['a', 'b', 'c']) > > >>> n2 = namedtuple('f', ['a', 'b', 'c']) > > >>> n1 is n2 > > False > > > > I found that surprising, as I expected the named tuple type to be > > cached based on the declared name 'f'. But it's been that way > forever > > so obviously my intuition here is wrong. But maybe it would be > useful > > for this case if there *was* a way to base named tuple > identity off > > the name/fields? It could be as simple as caching the results: > > > > >>> from functools import lru_cache > > >>> cached_namedtuple = lru_cache(None)(namedtuple) > > >>> n1 = cached_namedtuple('f', ('a', 'b', 'c')) # A tuple rather > > than a list of field names, as lists aren't hashable > > >>> n2 = cached_namedtuple('f', ('a', 'b', 'c')) > > >>> n1 is n2 > > True > > > > Paul > > > > > > > > -- > > --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido> > <http://python.org/~guido>) > > /Pronouns: he/him/his //(why is my pronoun here?)/ > > > <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> > > > > _______________________________________________ > > Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> > <mailto:python-dev@python.org <mailto:python-dev@python.org>> > > To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@python.org> > <mailto:python-dev-leave@python.org <mailto:python-dev-leave@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/GIFRTFWP... > > > > > -- > Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> > <mailto:tismer@stackless.com <mailto:tismer@stackless.com>> > Software Consulting : http://www.stackless.com/ > Karl-Liebknecht-Str. 121 : https://github.com/PySide > 14482 Potsdam : GPG key -> 0xFB7BEE0E > phone +49 173 24 18 776 fax +49 (30) 700143-0023 > > > > -- > --Guido van Rossum (python.org/~guido <http://python.org/~guido> <http://python.org/~guido>) > /Pronouns: he/him/his //(why is my pronoun here?)/ > <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> > > _______________________________________________ > Python-Dev mailing list -- python-dev@python.org <mailto:python-dev@python.org> > To unsubscribe send an email to python-dev-leave@python.org <mailto:python-dev-leave@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/QZ44KHLL... >
-- Christian Tismer :^) tismer@stackless.com <mailto:tismer@stackless.com> Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him/his //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@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/D3LTF3V2...
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On Thu, 8 Aug 2019 at 17:17, Christian Tismer <tismer@stackless.com> wrote:
Yes, that's what I mean. Probably retval or whatever people prefer would be adequate, with a special rule if that name is taken.
I think btw. that using StructSequence(somename=sometype, ..., ) that does a dict lookup is quite appealing. It returns a class like stat_result, but the function call shows its arguments (see answer to Ronald).
Ciao -- Chris
Just a little comment: there is a (vague) plan to add a feature (key types) to the type system that will allow user-defined constructs similar to NamedTuple (for example StructSequence you mention). However, taking into account current schedule it is unlikely it will be added before mid-2020, so your best bet is indeed using ad-hoc named tuples. -- Ivan
On 12.08.19 10:52, Ivan Levkivskyi wrote:
On Thu, 8 Aug 2019 at 17:17, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Yes, that's what I mean. Probably retval or whatever people prefer would be adequate, with a special rule if that name is taken.
I think btw. that using StructSequence(somename=sometype, ..., ) that does a dict lookup is quite appealing. It returns a class like stat_result, but the function call shows its arguments (see answer to Ronald).
Ciao -- Chris
Just a little comment: there is a (vague) plan to add a feature (key types) to the type system that will allow user-defined constructs similar to NamedTuple (for example StructSequence you mention). However, taking into account current schedule it is unlikely it will be added before mid-2020, so your best bet is indeed using ad-hoc named tuples.
Interesting! Can I read something more about this? I'm curious ;-) But I guess it will anyway take a little time until I can make that transition. Maybe it's better to see what's coming up with typing, mypy, typing_inspect and friends. Well, I will probably start a prototype dev branch for that. Cheers -- Chris -- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
On Mon, 12 Aug 2019 at 11:24, Christian Tismer <tismer@stackless.com> wrote:
On 12.08.19 10:52, Ivan Levkivskyi wrote:
On Thu, 8 Aug 2019 at 17:17, Christian Tismer <tismer@stackless.com <mailto:tismer@stackless.com>> wrote:
Yes, that's what I mean. Probably retval or whatever people prefer would be adequate, with a special rule if that name is taken.
I think btw. that using StructSequence(somename=sometype, ..., ) that does a dict lookup is quite appealing. It returns a class like stat_result, but the function call shows its arguments (see answer to Ronald).
Ciao -- Chris
Just a little comment: there is a (vague) plan to add a feature (key types) to the type system that will allow user-defined constructs similar to NamedTuple (for example StructSequence you mention). However, taking into account current schedule it is unlikely it will be added before mid-2020, so your best bet is indeed using ad-hoc named tuples.
Interesting! Can I read something more about this? I'm curious ;-)
Some preliminary ideas were discussed at one of recent typing summits, see https://paper.dropbox.com/doc/Type-system-improvements--AfxnxPOd_hhYvtamiI9n... -- Ivan
On 7/29/19 4:36 PM, Christian Tismer wrote:
Hi friends,
I am meanwhile the PySide maintainer at The Qt Company, and we are trying to make the mapping from Qt functions to Python functions as comparable as possible.
One problem are primitive pointer variables: In Qt, it is natural to use "sometype *varname" to make a mutable variable. In Python, you have to turn such a thing into a result-tuple. Example:
void QPrinter::getPageMargins(qreal *left, qreal *top, \ qreal *right, qreal *bottom, QPrinter::Unit unit) const
(meanwhile deprecated, but a good example)
is mapped to the Python signature
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.Tuple[float, float, float, float]: ...
NOW my question: ----------------
I would like to retain the variable names in Python! The first idea is to use typing.NamedTuple, but I get the impression that this would be too much, because I would not only need to create an extra named tuple definition for every set of names, but also invent a name for that named tuple.
What I would like to have is something that looks like
def getPageMargins(self, \ unit: PySide2.QtPrintSupport.QPrinter.Unit) \ -> typing.NamedTuple[left: float, top: float, \ right:float, bottom:float]: ...
but that is obviously not a named tuple. Possible would be to derive a name from the function, so maybe a definition could be used like
class PageMargingResult(NamedTuple): left: float top: float right: float bottom: float
but then I would have some opaque PageMargingResult type. This would work, but as said, this is a bit too much, since I only wanted something like a tuple with names.
What do you suggest to do here? Something what I am missing?
Hello, I'm afraid you're stuck with defining a new type for each of these. One reason why that's better is that info about the names will only be stored once, in the type; not in every instance. Since this is in PySide, I assume you're using the C-API. If that's the case, check out Struct Sequences, the "C equivalent of named tuples". For example, the result of "os.stat()" is a struct sequence. https://docs.python.org/3/c-api/tuple.html#struct-sequence-objects Note that like namedtuples, these are immutable, and they're proper subclasses of tuple.
Hi Petr, hi Paul, the struct sequence objects are in fact interesting! About the "every instance" issue: Well, if I used something like the caching approach from Paul's post, like cached_namedtuple = lru_cache(None)(namedtuple) n1 = cached_namedtuple('f', ('a', 'b', 'c')) n2 = cached_namedtuple('f', ('a', 'b', 'c')) n1 is n2 which produces uniqueness, then I would need no explicit names. How about that principle, but with the struct sequence objects? Cheers -- Chris On 30.07.19 11:13, Petr Viktorin wrote:
Hello, I'm afraid you're stuck with defining a new type for each of these. One reason why that's better is that info about the names will only be stored once, in the type; not in every instance.
Since this is in PySide, I assume you're using the C-API. If that's the case, check out Struct Sequences, the "C equivalent of named tuples". For example, the result of "os.stat()" is a struct sequence.
https://docs.python.org/3/c-api/tuple.html#struct-sequence-objects
Note that like namedtuples, these are immutable, and they're proper subclasses of tuple.
-- Christian Tismer :^) tismer@stackless.com Software Consulting : http://www.stackless.com/ Karl-Liebknecht-Str. 121 : https://github.com/PySide 14482 Potsdam : GPG key -> 0xFB7BEE0E phone +49 173 24 18 776 fax +49 (30) 700143-0023
participants (6)
-
Christian Tismer
-
Guido van Rossum
-
Ivan Levkivskyi
-
Paul Moore
-
Petr Viktorin
-
Ronald Oussoren