argparse modify

Roel Schroeven roel at roelschroeven.net
Fri Jun 24 07:29:57 EDT 2022


Op 24/06/2022 om 0:32 schreef Dennis Lee Bieber:
> On Thu, 23 Jun 2022 18:57:31 +0200, "Dieter Maurer"<dieter at handshake.de>
> declaimed the following:
>
> >??? ???? wrote at 2022-6-23 15:31 +0300:
> >>how to solve this (argparse)
>
> >>    MAXREPEAT = _NamedIntConstant(32,name=str(32))
> >>TypeError: 'name' is an invalid keyword argument for int()
> >
> >This does not look like an `argparse` problem:
> >the traceback comes from `oracle/RTR.py`.
>
> 	And the listed code looks quite suspicious to me...
>
> >>     class _NamedIntConstant(int):
> >>         def __init__(cls, value):
> >>             self = super(_NamedIntConstant, cls).__init__(cls, value)
> >>             self.name = name
> >>             return self
>
> 	There does not appear to be any provision for keyword arguments at all.
> The only use of "name" is to an undefined object.
>
The code seems to be a copy of Lib/re/_constants.py (or 
Lib/sre_constants.py before commit 
1be3260a90f16aae334d993aecf7b70426f98013), but in _constants.py that 
class uses __new__ instead of __init__:

     class _NamedIntConstant(int):
         def __new__(cls, value, name):
             self = super(_NamedIntConstant, cls).__new__(cls, value)
             self.name = name
             return self

         def __repr__(self):
             return self.name

         __reduce__ = None

(unless still older versions did use __init__)

It's used there as a kind of enum. I guess that code was originally 
written before Python had enum.Enum. _makecodes() uses it so create 
named int objects from its arguments, with automatically generated 
consecutive int values, places them in the global namespace (feels like 
a code smell to me) and also returns them.

     def _makecodes(*names):
         items = [_NamedIntConstant(i, name) for i, name in 
enumerate(names)]
         globals().update({item.name: item for item in items})
         return items

     # operators
     OPCODES = _makecodes(
         # failure=0 success=1 (just because it looks better that way :-)
         'FAILURE', 'SUCCESS',

         'ANY', 'ANY_ALL',
         'ASSERT', 'ASSERT_NOT',
         'AT',
         # ...
         )

נתי שטרן, are you trying to use that semi-enum functionality? Most 
likely you're better of using enum.Enum instead.

-- 
"You can fool some of the people all the time, and all of the people some
of the time, but you cannot fool all of the people all of the time."
         -- Abraham Lincoln
"You can fool too many of the people too much of the time."
         -- James Thurber


More information about the Python-list mailing list