@@ -163,14 +163,16 @@ def entry_function(opt):
163
163
import copy
164
164
import json
165
165
import argparse
166
+ import sys
166
167
from argparse import ArgumentParser
167
168
from configparser import ConfigParser
168
169
from inspect import getfullargspec
169
170
from functools import wraps
170
171
from pathlib import Path
171
172
from textwrap import wrap
173
+ from typing import Callable , Mapping
172
174
173
- from generic_parser .tools import DotDict , silence , unformatted_console_logging
175
+ from generic_parser .tools import DotDict , silence , unformatted_console_logging , StringIO , log_out
174
176
from generic_parser .dict_parser import ParameterError , ArgumentError , DictParser
175
177
176
178
import logging
@@ -186,8 +188,8 @@ def entry_function(opt):
186
188
# EntryPoint Class #############################################################
187
189
188
190
189
- class EntryPoint ( object ) :
190
- def __init__ (self , parameter , strict = False ):
191
+ class EntryPoint :
192
+ def __init__ (self , parameter , strict : bool = False , argument_parser_args : Mapping = None , help_printer : Callable = None ):
191
193
"""Initialize decoration: Handle the desired input parameter."""
192
194
self .strict = strict
193
195
@@ -203,8 +205,9 @@ def __init__(self, parameter, strict=False):
203
205
# this also ensures that the parameters are correctly defined,
204
206
# by tests in argparser and in Parameter(),
205
207
# which is used in dict_parser -> add parameter
206
- self .argparse = self ._create_argument_parser ()
208
+ self .argparse = self ._create_argument_parser (argument_parser_args )
207
209
self .dictparse = self ._create_dict_parser () # also used for configfiles
210
+ self ._help_printer = help_printer
208
211
209
212
def parse (self , * args , ** kwargs ):
210
213
"""
@@ -252,9 +255,14 @@ def _create_config_argument(self):
252
255
parser .add_argument ('--{}' .format (ID_SECTION ), type = str , dest = ID_SECTION ,)
253
256
return parser
254
257
255
- def _create_argument_parser (self ):
258
+ def _create_argument_parser (self , args_dict : Mapping ):
256
259
"""Creates the ArgumentParser from parameter."""
257
- parser = ArgumentParser ()
260
+
261
+ if args_dict :
262
+ parser = ArgumentParser (** args_dict )
263
+ else :
264
+ parser = ArgumentParser ()
265
+
258
266
parser = _add_params_to_argument_parser (parser , self .parameter )
259
267
return parser
260
268
@@ -281,7 +289,26 @@ def _handle_commandline(self, args=None):
281
289
options = self .configarg .parse_args (args )
282
290
except SystemExit :
283
291
# parse regular options
284
- options , unknown_opts = self .argparse .parse_known_args (args )
292
+ errors_io = StringIO ()
293
+ try :
294
+ with log_out (stderr = errors_io ): # errors go into errors_io
295
+ options , unknown_opts = self .argparse .parse_known_args (args )
296
+ except SystemExit as e :
297
+ errors_str = errors_io .getvalue ()
298
+ # print help on wrong input
299
+ if self ._help_printer and e .code == 2 : # code 0 means help has been printed
300
+ self ._help_printer (self .argparse .format_help ())
301
+ # remove duplicated "usage" line
302
+ errors_str = "\n " .join (errors_str .split ("\n " )[- 2 :])
303
+
304
+ # print errors now (if any)
305
+ sys .stderr .write (errors_str )
306
+ raise e
307
+
308
+ # print help, even if passed on to other parser
309
+ if self ._help_printer and "--help" in unknown_opts :
310
+ self ._help_printer (self .argparse .format_help ())
311
+
285
312
options = DotDict (vars (options ))
286
313
if self .strict :
287
314
if unknown_opts :
0 commit comments