@@ -1233,7 +1233,9 @@ def __call__(self, parser, namespace, values, option_string=None):
1233
1233
# namespace for the relevant parts.
1234
1234
subnamespace , arg_strings = parser .parse_known_args (arg_strings , None )
1235
1235
for key , value in vars (subnamespace ).items ():
1236
- setattr (namespace , key , value )
1236
+ if key != '__defaults__' :
1237
+ setattr (namespace , key , value )
1238
+ namespace .__defaults__ .update (subnamespace .__defaults__ )
1237
1239
1238
1240
if arg_strings :
1239
1241
vars (namespace ).setdefault (_UNRECOGNIZED_ARGS_ATTR , [])
@@ -1308,21 +1310,36 @@ def __repr__(self):
1308
1310
class Namespace (_AttributeHolder ):
1309
1311
"""Simple object for storing attributes.
1310
1312
1313
+ Default values are stored in a dict name `__defaults__` so they won't mess
1314
+ with the given values.
1315
+
1311
1316
Implements equality by attribute names and values, and provides a simple
1312
1317
string representation.
1313
1318
"""
1314
1319
1315
1320
def __init__ (self , ** kwargs ):
1316
1321
for name in kwargs :
1317
1322
setattr (self , name , kwargs [name ])
1323
+ self .__defaults__ = {}
1324
+
1325
+ def _get_kwargs (self ):
1326
+ kwargs = self .__defaults__ | self .__dict__
1327
+ kwargs .pop ('__defaults__' , None )
1328
+ return list (kwargs .items ())
1329
+
1330
+ def __getattr__ (self , name ):
1331
+ try :
1332
+ return self .__defaults__ [name ]
1333
+ except KeyError :
1334
+ raise AttributeError (name )
1318
1335
1319
1336
def __eq__ (self , other ):
1320
1337
if not isinstance (other , Namespace ):
1321
1338
return NotImplemented
1322
- return vars (self ) == vars (other )
1339
+ return dict (self . _get_kwargs ()) == dict (other . _get_kwargs () )
1323
1340
1324
1341
def __contains__ (self , key ):
1325
- return key in self .__dict__
1342
+ return key in self .__dict__ or key in self . __defaults__
1326
1343
1327
1344
1328
1345
class _ActionsContainer (object ):
@@ -1880,14 +1897,13 @@ def parse_known_args(self, args=None, namespace=None):
1880
1897
# add any action defaults that aren't present
1881
1898
for action in self ._actions :
1882
1899
if action .dest is not SUPPRESS :
1883
- if not hasattr (namespace , action .dest ):
1884
- if action .default is not SUPPRESS :
1885
- setattr (namespace , action .dest , action .default )
1900
+ if action .default is not SUPPRESS and action .dest not in namespace :
1901
+ namespace .__defaults__ [action .dest ] = action .default
1886
1902
1887
1903
# add any parser defaults that aren't present
1888
1904
for dest in self ._defaults :
1889
- if not hasattr ( namespace , dest ) :
1890
- setattr ( namespace , dest , self ._defaults [dest ])
1905
+ if dest not in namespace :
1906
+ namespace . __defaults__ [ dest ] = self ._defaults [dest ]
1891
1907
1892
1908
# parse the arguments and exit if there are any errors
1893
1909
if self .exit_on_error :
@@ -2124,12 +2140,11 @@ def consume_positionals(start_index):
2124
2140
# parsing arguments to avoid calling convert functions
2125
2141
# twice (which may fail) if the argument was given, but
2126
2142
# only if it was defined already in the namespace
2127
- if (action .default is not None and
2128
- isinstance (action .default , str ) and
2129
- hasattr (namespace , action .dest ) and
2130
- action .default is getattr (namespace , action .dest )):
2131
- setattr (namespace , action .dest ,
2132
- self ._get_value (action , action .default ))
2143
+ if (isinstance (action .default , str ) and
2144
+ action .dest in namespace and
2145
+ getattr (namespace , action .dest ) is action .default ):
2146
+ namespace .__defaults__ [action .dest ] = self ._get_value (
2147
+ action , action .default )
2133
2148
2134
2149
if required_actions :
2135
2150
self .error (_ ('the following arguments are required: %s' ) %
0 commit comments