ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaCommon
python
AthArgumentParser.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3
""" Helper wrapper to argparse.ArgumentParser for use in athena
4
5
The user's options are separated from athena's command line arguments by a
6
single '-' character when athena is called.
7
8
Public classes:
9
AthArgumentParser
10
11
Usage:
12
from AthenaCommon.AthArgumentParser import AthArgumentParser
13
parser = AthArgumentParser()
14
parser.add_argument("-a", "--arg", action="store", help="Argument")
15
16
args = parser.parse_args()
17
print(args.arg) # etc
18
"""
19
20
import
argparse
21
import
sys
22
import
inspect
23
import
os
24
from
subprocess
import
Popen, PIPE
25
26
# import the command line options back from the main process.
27
# This means that this code only runs in something like an athena call.
28
from
__main__
import
opts
29
30
31
class
AthArgumentParser
(argparse.ArgumentParser):
32
""" Parse user commandline arguments in a job option. """
33
34
def
__init__
(self, jo_name=None, prog=None, print_caller_help=True, **kwargs):
35
""" Create the parser
36
---------
37
Arguments
38
---------
39
jo_name:
40
The name of the calling job option, used to format the help
41
text. Will attempt to deduce it if possible
42
prog:
43
The start of the usage message, usually can be deduced
44
print_caller_help:
45
Whether or not to print the help text from the calling program
46
(usually athena)
47
48
All other keyword arguments are forwarded to the base class
49
constructor
50
"""
51
52
caller = sys.argv[0]
53
if
prog
is
None
:
54
if
jo_name
is
None
:
55
# Use inspect to find which job option we're in. This isn't
56
# completely foolproof but it's just a cosmetic detail so
57
# doesn't need to be
58
for
frame
in
inspect.stack():
59
# For each frame in the stack, check the file name and keep
60
# it if it matches one of the scripts supplied
61
fname = inspect.getfile(frame[0])
62
try
:
63
jo_name = next(
64
script
for
script
in
opts.scripts
if
fname.endswith(script)
65
)
66
break
67
except
StopIteration:
68
pass
69
else
:
70
# fallback name
71
jo_name =
"User job option"
72
prog =
"{0} {1} [{0} options] -"
.format(os.path.basename(caller), jo_name)
73
if
print_caller_help:
74
# Get the help options for the caller
75
caller_help, _ = Popen(
76
[caller,
"--help"
], stdout=PIPE, stderr=PIPE
77
).communicate()
78
# decode from bytes
79
caller_help = caller_help.decode(
"utf-8"
)
80
if
caller.endswith(
"athena.py"
):
81
# If this is being called from athena, we know that there are
82
# some lines to strip off
83
caller_help = caller_help.split(
"\n"
, 3)[3]
84
self.
caller_help
=
"{} options:\n{}"
.format(
85
os.path.basename(caller), caller_help
86
)
87
else
:
88
self.
caller_help
=
""
89
super().
__init__
(prog=prog, **kwargs)
90
super().
add_argument
(
91
"remaining scripts"
,
92
nargs=
"*"
,
93
help=
"Any remaining scripts to be run by athena after this job option. Mainly used to run the 'post' script on the grid."
,
94
)
95
96
def
add_argument
(self, *args, **kwargs):
97
""" Add a new argument
98
99
The difference between this and the base class is that it disallows
100
adding positional arguments which are reserved by athena for job
101
options. In particular, even if user code uses only one job option
102
(which is common) pathena will add more when running on the grid
103
"""
104
if
not
args
or
len(args)
and
args[0][0]
not
in
self.
prefix_chars
:
105
raise
ValueError(
106
"Positional arguments are not allowed! Defining them could mess up grid running!"
107
)
108
return
super().
add_argument
(*args, **kwargs)
109
110
def
parse_args
(self, args=None, namespace=None):
111
""" Override the base class to use the leftover athena argumnets by
112
default
113
"""
114
if
args
is
None
:
115
args = opts.user_opts
116
return
super().
parse_args
(args, namespace)
117
118
def
parse_known_args
(self, args=None, namespace=None):
119
""" Override the base class to use the leftover athena argumnets by
120
default
121
"""
122
if
args
is
None
:
123
args = opts.user_opts
124
return
super().
parse_known_args
(args, namespace)
125
126
def
format_help
(self):
127
text = super().
format_help
()
128
return
"\n"
.join([text, self.
caller_help
])
python.AthArgumentParser.AthArgumentParser
Definition
AthArgumentParser.py:31
python.AthArgumentParser.AthArgumentParser.__init__
__init__(self, jo_name=None, prog=None, print_caller_help=True, **kwargs)
Definition
AthArgumentParser.py:34
python.AthArgumentParser.AthArgumentParser.format_help
format_help(self)
Definition
AthArgumentParser.py:126
python.AthArgumentParser.AthArgumentParser.caller_help
str caller_help
Definition
AthArgumentParser.py:84
python.AthArgumentParser.AthArgumentParser.parse_args
parse_args(self, args=None, namespace=None)
Definition
AthArgumentParser.py:110
python.AthArgumentParser.AthArgumentParser.add_argument
add_argument(self, *args, **kwargs)
Definition
AthArgumentParser.py:96
python.AthArgumentParser.AthArgumentParser.parse_known_args
parse_known_args(self, args=None, namespace=None)
Definition
AthArgumentParser.py:118
python.AthArgumentParser.AthArgumentParser.prefix_chars
prefix_chars
Definition
AthArgumentParser.py:104
Generated on
for ATLAS Offline Software by
1.17.0