Author gousaiyang
Recipients gousaiyang
Date 2020-04-12.19:46:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1586720778.53.0.603692808459.issue40265@roundup.psfhosted.org>
In-reply-to
Content
It is generally a convention to design the repr string such that `eval(repr(obj))` can reproduce the object. Issue 24360 handles the special situation when arg name passed to `argparse.Namespace` is not a valid identifier:

>>> from argparse import Namespace
>>> Namespace(**{')': 3})
Namespace(**{')': 3})

However there is one more corner case to handle: the arg name could be a reserved keyword.

>>> Namespace(**{'return': 3})
Namespace(return=3)
>>> Namespace(return=3)
  File "<stdin>", line 1
    Namespace(return=3)
              ^
SyntaxError: invalid syntax

I noticed that the documentation of `str.isidentifier` tells me to also check for keywords with `keyword.iskeyword`. However `__debug__` is not considered a keyword by `keyword.iskeyword`, but cannot be assigned to:

>>> keyword.iskeyword('__debug__')
False
>>> Namespace(**{'__debug__':3})
Namespace(__debug__=3)
>>> Namespace(__debug__=3)
  File "<stdin>", line 1
SyntaxError: cannot assign to __debug__

I propose to enhance the arg name check in `argparse._AttributeHolder` from `if name.isidentifier():` to `if name.isidentifier() and not keyword.iskeyword(name) and name != '__debug__:'` to fix this. However this may slow down the argparse library since it will need to `import keyword` at the beginning, and `__repr__` will also be slower due to the added arg name checks.

By the way, when I came across issue 39076, I noticed that `types.SimpleNamespace` is not considering this problem at all:

>>> types.SimpleNamespace(**{')': 1, 'return': 2})
namespace()=1, return=2)
History
Date User Action Args
2020-04-12 19:46:18gousaiyangsetrecipients: + gousaiyang
2020-04-12 19:46:18gousaiyangsetmessageid: <1586720778.53.0.603692808459.issue40265@roundup.psfhosted.org>
2020-04-12 19:46:18gousaiyanglinkissue40265 messages
2020-04-12 19:46:18gousaiyangcreate