[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Erik Montnemery


Erik Montnemery  added the comment:

Maybe something like this:

diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 735d477db4..8de913d8db 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -1291,7 +1291,8 @@ These are not used in annotations. They are building 
blocks for declaring types.

 .. class:: NamedTuple

-   Typed version of :func:`collections.namedtuple`.
+   Typed version of :func:`collections.namedtuple`, annotated fields are passed
+   to an underlying `collections.namedtuple`.

Usage::

@@ -1311,9 +1312,20 @@ These are not used in annotations. They are building 
blocks for declaring types.

   employee = Employee('Guido')
   assert employee.id == 3
+  assert employee == ('Guido', 3)

Fields with a default value must come after any fields without a default.

+   Non-annotated fields will not be part of the `collections.namedtuple`::
+
+  class Employee(NamedTuple):
+  name = 'Guido'
+  id = 3
+
+  employee = Employee()
+  assert employee.id == 3
+  assert not employee  # Passes because the collections.namedtuple is empty
+
The resulting class has an extra attribute ``__annotations__`` giving a
dict that maps the field names to the field types.  (The field names are in

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Alex Waygood


Alex Waygood  added the comment:

To me, the fact that NamedTuple uses class attributes to provide field defaults 
feels like an implementation detail that is only relevant to an unusual edge 
case.

Where do you think the documentation should be improved, and what is your 
suggested wording? :)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Erik Montnemery


Erik Montnemery  added the comment:

I think elaborating in the documentation that only annotated attributes make it 
to the underlying namedtuple() would be helpful, it's not obvious that they are 
instead just class attributes.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Alex Waygood


Alex Waygood  added the comment:

I agree that prohibiting zero-length NamedTuples seems like a bad idea, and 
also agree that this probably doesn't need to be documented.

The behaviour here definitely looks weird at first glance, but it's probably 
not a good idea to tamper with the __bool__() methods of NamedTuple classes 
either: an empty NamedTuple probably *should* be falsey by default, even if it 
has a class attribute.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Eric V. Smith


Eric V. Smith  added the comment:

I don't think we'd want to prohibit zero-length namedtuples (or NamedTuples). 
I've used them, especially when I'm dynamically creating them.

This is just a side effect of how Python works. I don't think there's anything 
to do here, except maybe mention it in the docs, and I'm not even sure that's a 
good idea.

--
nosy: +eric.smith

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Spencer Brown


Spencer Brown  added the comment:

What's happening is that typing.NamedTuple ignores non-annotated attributes 
entirely when computing the names it passes along to namedtuple(), so here "a" 
is just a class attribute. You're accessing it from there, but the tuple itself 
is entirely empty. Perhaps it should error out if no names at all are found?

--
nosy: +Spencer Brown

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Alex Waygood


Change by Alex Waygood :


--
components: +Library (Lib)
nosy: +AlexWaygood, gvanrossum, kj

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue45972] typing.NamedTuple with default arguments without type annotations is falsy

2021-12-03 Thread Erik Montnemery


New submission from Erik Montnemery :

typing.NamedTuple behaves in surprising ways when it has default arguments 
which lack type annotations:

>>> from typing import NamedTuple
>>> class MyTuple(NamedTuple):
... a = 1000
...
>>> tmp = MyTuple()
>>> tmp.a
1000
>>> len(tmp)
0
>>> bool(tmp)
False

Tested in Python 3.8 and 3.9

--
messages: 407570
nosy: emontnemery
priority: normal
severity: normal
status: open
title: typing.NamedTuple with default arguments without type annotations is 
falsy
type: behavior
versions: Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com