Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from inspect import Parameter 

2from logging import getLogger 

3import datetime 

4import enum 

5import argparse 

6import argparse_utils 

7from .parser import Parser 

8 

9log = getLogger(__name__) 

10 

11 

12class Argparse: 

13 parser = Parser() 

14 

15 def __init__(self, positional: bool = False): 

16 self.positional = positional 

17 

18 def onearg(self, arg, p): 

19 optname = arg.get("name") 

20 if len(optname) == 1: 

21 optname = "-" + optname 

22 else: 

23 optname = "--" + optname 

24 kwargs = { 

25 'type': arg.get("type", str), 

26 'default': arg.get("default"), 

27 'help': arg.get("doc"), 

28 'metavar': arg.get('type', str).__name__, 

29 } 

30 # custom action 

31 if kwargs.get('type') == datetime.datetime: 

32 kwargs['action'] = argparse_utils.datetime_action() 

33 kwargs.pop('type') 

34 elif kwargs.get('type') == datetime.date: 

35 kwargs['action'] = argparse_utils.date_action() 

36 kwargs.pop('type') 

37 elif kwargs.get('type') == datetime.time: 

38 kwargs['action'] = argparse_utils.time_action() 

39 kwargs.pop('type') 

40 elif kwargs.get('type') == datetime.timedelta: 

41 kwargs['action'] = argparse_utils.timedelta_action() 

42 kwargs.pop('type') 

43 elif issubclass(kwargs.get('type'), enum.Enum): 

44 kwargs['action'] = argparse_utils.enum_action(kwargs.get('type')) 

45 kwargs['help'] = "/".join(kwargs.get('type').__members__.keys()) 

46 kwargs.pop('type') 

47 elif kwargs.get('type') == dict: 

48 kwargs['action'] = argparse_utils.json_action() 

49 kwargs.pop('type') 

50 elif kwargs.get('type') == bool: 

51 kwargs.pop('type') 

52 kwargs.pop('metavar') 

53 if kwargs.get('default', False): 

54 kwargs['action'] = "store_false" 

55 else: 

56 kwargs['action'] = "store_true" 

57 log.debug("kwargs %s", kwargs) 

58 

59 # by kind(positional/keyword) 

60 if arg.get("kind") == Parameter.POSITIONAL_ONLY: 

61 p.add_argument(arg.get("name"), **kwargs) 

62 elif arg.get("kind") == Parameter.VAR_POSITIONAL: 

63 p.add_argument(arg.get("name"), nargs='*', **kwargs) 

64 elif arg.get("kind") == Parameter.VAR_KEYWORD: 

65 pass 

66 # p.add_argument(optname, **kwargs) 

67 elif arg.get("kind") == Parameter.POSITIONAL_OR_KEYWORD: 

68 if self.positional: 

69 p.add_argument(arg.get("name"), nargs=1, **kwargs) 

70 else: 

71 p.add_argument(optname, **kwargs) 

72 elif arg.get("kind") == Parameter.KEYWORD_ONLY: 

73 p.add_argument(optname, **kwargs) 

74 

75 def convert_fn(self, name, data, p=None): 

76 log.debug("convert_fn name=%s, data=%s", name, data) 

77 if p is None: 

78 p = argparse.ArgumentParser(prog=name, description=data.get("doc")) 

79 else: 

80 p.description = data.get("doc") 

81 p.set_defaults(__FUNCNAME__=name, __FUNC__=data.get("fn")) 

82 log.debug("fn %s, args=%s", name, [ 

83 x.get("name") for x in data.get("args", [])]) 

84 args = self.parser.fn_args(data) 

85 log.debug("args=%s", [x.get("name") for x in args]) 

86 for i in args: 

87 self.onearg(i, p) 

88 return p 

89 

90 def convert_cls(self, data, p=None): 

91 if p is None: 

92 name = data.get("__classmeta__", {}).get("name") 

93 p = argparse.ArgumentParser(prog=name, description=data.get("doc")) 

94 else: 

95 p.description = data.get("doc") 

96 p.set_defaults(__CLASSMETA__=data.get("__classmeta__")) 

97 self.convert_fn("new", data.get("__init__"), p) 

98 subs = p.add_subparsers() 

99 for k, v in data.items(): 

100 log.debug("do1 k=%s v=%s", k, v) 

101 if k == "__classmeta__": 

102 log.debug("classmeta %s", v) 

103 continue 

104 if k == "__init__": 

105 log.debug("new %s", v) 

106 continue 

107 if k == "doc": 

108 log.debug("doc %s", v) 

109 continue 

110 s = subs.add_parser(k, help=v.get("doc")) 

111 self.convert_fn(k, v, s) 

112 return p 

113 

114 def fn_arg(self, fdata, parsed): 

115 kw = {} 

116 pos = [] 

117 for ag in fdata.get("args", []): 

118 name = ag.get("name") 

119 if name is None: 

120 log.debug("name is none") 

121 continue 

122 if not hasattr(parsed, name): 

123 log.debug("has no %s", name) 

124 continue 

125 if ag.get("kind") in (Parameter.POSITIONAL_ONLY, Parameter.VAR_POSITIONAL): 

126 pos.extend(getattr(parsed, name)) 

127 elif ag.get("kind") == Parameter.POSITIONAL_OR_KEYWORD and self.positional: 

128 pos.extend(getattr(parsed, name)) 

129 else: 

130 kw[name] = getattr(parsed, name) 

131 return kw, pos 

132 

133 def split_arg(self, data, parsed): 

134 carg_kw, carg_pos = self.fn_arg(data.get("__init__", {}), parsed) 

135 farg_kw, farg_pos = self.fn_arg( 

136 data.get(parsed.__FUNCNAME__, {}), parsed) 

137 return ((carg_pos, carg_kw), (farg_pos, farg_kw))