Skip to content

Commit 600564b

Browse files
JoschDfsoubelet
andauthored
Argparse options (#56)
* help handling * added parser opts and help * remove object inheritance for base classes * bump version Co-authored-by: Felix Soubelet <[email protected]>
1 parent 961e7a4 commit 600564b

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

generic_parser/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
__title__ = "generic_parser"
66
__description__ = "A parser for arguments and config-files that also allows direct python input."
77
__url__ = "https://github.com/pylhc/generic_parser"
8-
__version__ = "1.0.9"
8+
__version__ = "1.1.0"
99
__author__ = "pylhc"
1010
__author_email__ = "[email protected]"
1111
__license__ = "MIT"

generic_parser/dict_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Parser #######################################################################
1818

1919

20-
class DictParser(object):
20+
class DictParser:
2121
"""
2222
Provides functions to parse a dictionary.
2323
@@ -393,7 +393,7 @@ class ArgumentError(Exception):
393393
pass
394394

395395

396-
class Parameter(object):
396+
class Parameter:
397397
"""Helper Class for DictParser."""
398398
def __init__(self, name, **kwargs):
399399
self.name = name

generic_parser/entrypoint_parser.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,16 @@ def entry_function(opt):
163163
import copy
164164
import json
165165
import argparse
166+
import sys
166167
from argparse import ArgumentParser
167168
from configparser import ConfigParser
168169
from inspect import getfullargspec
169170
from functools import wraps
170171
from pathlib import Path
171172
from textwrap import wrap
173+
from typing import Callable, Mapping
172174

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
174176
from generic_parser.dict_parser import ParameterError, ArgumentError, DictParser
175177

176178
import logging
@@ -186,8 +188,8 @@ def entry_function(opt):
186188
# EntryPoint Class #############################################################
187189

188190

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):
191193
"""Initialize decoration: Handle the desired input parameter."""
192194
self.strict = strict
193195

@@ -203,8 +205,9 @@ def __init__(self, parameter, strict=False):
203205
# this also ensures that the parameters are correctly defined,
204206
# by tests in argparser and in Parameter(),
205207
# 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)
207209
self.dictparse = self._create_dict_parser() # also used for configfiles
210+
self._help_printer = help_printer
208211

209212
def parse(self, *args, **kwargs):
210213
"""
@@ -252,9 +255,14 @@ def _create_config_argument(self):
252255
parser.add_argument('--{}'.format(ID_SECTION), type=str, dest=ID_SECTION,)
253256
return parser
254257

255-
def _create_argument_parser(self):
258+
def _create_argument_parser(self, args_dict: Mapping):
256259
"""Creates the ArgumentParser from parameter."""
257-
parser = ArgumentParser()
260+
261+
if args_dict:
262+
parser = ArgumentParser(**args_dict)
263+
else:
264+
parser = ArgumentParser()
265+
258266
parser = _add_params_to_argument_parser(parser, self.parameter)
259267
return parser
260268

@@ -281,7 +289,26 @@ def _handle_commandline(self, args=None):
281289
options = self.configarg.parse_args(args)
282290
except SystemExit:
283291
# 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+
285312
options = DotDict(vars(options))
286313
if self.strict:
287314
if unknown_opts:

0 commit comments

Comments
 (0)