@@ -1215,7 +1215,9 @@ def __call__(self, parser, namespace, values, option_string=None):
1215
1215
# namespace for the relevant parts.
1216
1216
subnamespace , arg_strings = parser .parse_known_args (arg_strings , None )
1217
1217
for key , value in vars (subnamespace ).items ():
1218
- setattr (namespace , key , value )
1218
+ if key != '__defaults__' :
1219
+ setattr (namespace , key , value )
1220
+ namespace .__defaults__ .update (subnamespace .__defaults__ )
1219
1221
1220
1222
if arg_strings :
1221
1223
vars (namespace ).setdefault (_UNRECOGNIZED_ARGS_ATTR , [])
@@ -1290,21 +1292,36 @@ def __repr__(self):
1290
1292
class Namespace (_AttributeHolder ):
1291
1293
"""Simple object for storing attributes.
1292
1294
1295
+ Default values are stored in a dict name `__defaults__` so they won't mess
1296
+ with the given values.
1297
+
1293
1298
Implements equality by attribute names and values, and provides a simple
1294
1299
string representation.
1295
1300
"""
1296
1301
1297
1302
def __init__ (self , ** kwargs ):
1298
1303
for name in kwargs :
1299
1304
setattr (self , name , kwargs [name ])
1305
+ self .__defaults__ = {}
1306
+
1307
+ def _get_kwargs (self ):
1308
+ kwargs = self .__defaults__ | self .__dict__
1309
+ kwargs .pop ('__defaults__' , None )
1310
+ return list (kwargs .items ())
1311
+
1312
+ def __getattr__ (self , name ):
1313
+ try :
1314
+ return self .__defaults__ [name ]
1315
+ except KeyError :
1316
+ raise AttributeError (name )
1300
1317
1301
1318
def __eq__ (self , other ):
1302
1319
if not isinstance (other , Namespace ):
1303
1320
return NotImplemented
1304
- return vars (self ) == vars (other )
1321
+ return dict (self . _get_kwargs ()) == dict (other . _get_kwargs () )
1305
1322
1306
1323
def __contains__ (self , key ):
1307
- return key in self .__dict__
1324
+ return key in self .__dict__ or key in self . __defaults__
1308
1325
1309
1326
1310
1327
class _ActionsContainer (object ):
@@ -1862,14 +1879,13 @@ def parse_known_args(self, args=None, namespace=None):
1862
1879
# add any action defaults that aren't present
1863
1880
for action in self ._actions :
1864
1881
if action .dest is not SUPPRESS :
1865
- if not hasattr (namespace , action .dest ):
1866
- if action .default is not SUPPRESS :
1867
- setattr (namespace , action .dest , action .default )
1882
+ if action .default is not SUPPRESS and action .dest not in namespace :
1883
+ namespace .__defaults__ [action .dest ] = action .default
1868
1884
1869
1885
# add any parser defaults that aren't present
1870
1886
for dest in self ._defaults :
1871
- if not hasattr ( namespace , dest ) :
1872
- setattr ( namespace , dest , self ._defaults [dest ])
1887
+ if dest not in namespace :
1888
+ namespace . __defaults__ [ dest ] = self ._defaults [dest ]
1873
1889
1874
1890
# parse the arguments and exit if there are any errors
1875
1891
if self .exit_on_error :
@@ -2102,12 +2118,11 @@ def consume_positionals(start_index):
2102
2118
# parsing arguments to avoid calling convert functions
2103
2119
# twice (which may fail) if the argument was given, but
2104
2120
# only if it was defined already in the namespace
2105
- if (action .default is not None and
2106
- isinstance (action .default , str ) and
2107
- hasattr (namespace , action .dest ) and
2108
- action .default is getattr (namespace , action .dest )):
2109
- setattr (namespace , action .dest ,
2110
- self ._get_value (action , action .default ))
2121
+ if (isinstance (action .default , str ) and
2122
+ action .dest in namespace and
2123
+ getattr (namespace , action .dest ) is action .default ):
2124
+ namespace .__defaults__ [action .dest ] = self ._get_value (
2125
+ action , action .default )
2111
2126
2112
2127
if required_actions :
2113
2128
self .error (_ ('the following arguments are required: %s' ) %
0 commit comments