ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
AthenaCommon
python
Include.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3
# File: AthenaCommon/python/Include.py
4
# Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
5
6
"""Handle Athena options file inclusion. Files are located through the
7
JOBOPTSEARCHPATH envar and globally executed. If requested, files will be
8
traced. Note, however, that this option interferes with pdb and trace."""
9
10
import
os, sys, re, fnmatch
11
from
AthenaCommon.Utils.unixtools
import
FindFile
12
13
14
__version__ =
'1.3.0'
15
__author__ =
'Wim Lavrijsen (WLavrijsen@lbl.gov)'
16
17
__all__ = [
'include'
,
'marker'
,
'lineMarker'
,
'fidMarker'
,
18
'callMarker'
,
'returnMarker'
,
'activeMarker'
,
'silentMarker'
,
19
'tracedMarker'
]
20
21
marker =
' -+-'
22
__marker__ =
' -+-'
23
silentMarker =
' '
24
activeMarker =
'A'
25
tracedMarker =
'T'
26
callMarker =
'C'
27
returnMarker =
'R'
28
lineMarker =
'%3d'
29
fidMarker =
'%2d'
30
31
# do not trace any files that fnmatch these names:
32
excludeTracePattern = [
33
'*/GaudiPython/*'
,
'*/GaudiKernel/*'
,
# Gaudi framework files
34
'*/AthenaCommon/*'
,
# Athena framework files
35
'*/python%d.%d/*'
% sys.version_info[:2],
# python system
36
'*/python/*/*Conf.py'
,
# generated conf files
37
'*/PyUtils/decorator.py'
,
# very verbose
38
'*/PyUtils/Decorators.py'
,
# ditto
39
'*/PyUtils/Helper*.py'
,
# ditto
40
'*/lib/ROOT.py'
,
# ROOT import hook gets executed very many times
41
'*importlib._bootstrap*'
,
42
]
43
44
# unless they are explicitly included here:
45
includeTracePattern = [
'*/AthenaCommon/Bootstrap.py'
]
46
47
48
49
from
AthenaCommon
import
Logging
50
log = Logging.logging.getLogger(
'Athena'
)
51
52
class
IncludeError
( RuntimeError ):
53
pass
54
55
56
57
try
:
58
optionsPathEnv = os.environ[
'JOBOPTSEARCHPATH'
]
59
except
Exception:
60
optionsPathEnv = os.curdir
61
62
optionsPath = re.split(
',|'
+ os.pathsep, optionsPathEnv )
63
if
''
in
optionsPath:
64
optionsPath[ optionsPath.index(
''
) ] = str(os.curdir)
65
66
67
68
def
basename2
( fn ):
69
return
os.path.join( os.path.basename( os.path.dirname( fn ) ), os.path.basename( fn ) )
70
71
_filecache = {}
72
_linecache = {}
73
_notrcache = {}
74
75
class
Include
( object ):
76
fid = 0
77
78
def
__init__
( self, show = True, collect = 1, clean = False ):
79
self.
_show
= show
80
self.
_once
= []
81
self.
_fcurrent
=
''
82
self.
msg
= Logging.logging.getLogger(
'Athena'
)
83
84
if
clean:
85
self.
_workspace
= {}
86
else
:
87
import
__main__
88
self.
_workspace
= __main__.__dict__
89
90
if
collect:
91
self.
_collect
= 1
92
93
def
setShowIncludes
( self, show ):
94
self.
_show
= show
95
96
def
setCollect
( self, collect ):
97
if
collect
and
not
hasattr( self,
'_collect'
):
98
self.
_collect
= 1
99
elif
not
collect
and
hasattr( self,
'_collect'
):
100
del self.
_collect
101
102
def
setClean
( self, clean ):
103
import
__main__
104
if
clean:
105
if
self.
_workspace
is
__main__.__dict__:
106
self.
_workspace
= {}
107
self.
_workspace
.update( __main__.__dict__ )
108
else
:
109
self.
_workspace
= __main__.__dict__
110
111
def
__call__
( self, fn, *args, **kw ):
112
"""Include <fn> in the current scope by executing it globally."""
113
114
# some basic sanity check first
115
if
isinstance(fn, str)
and
len(fn) == 0:
116
raise
IncludeError(
"can not 'include' empty filenames"
)
117
118
# don't include file if not allowed (has to be exact match in py code)
119
if
fn
in
self._once:
120
self.msg.
debug
(
'file "%s" is blocked; not included'
, fn )
121
return
122
123
# locate the file
124
name = FindFile( os.path.expanduser( os.path.expandvars( fn ) ), optionsPath, os.R_OK )
125
if
not
name:
126
name = FindFile( os.path.basename( fn ), optionsPath, os.R_OK )
127
if
name:
128
self.msg.warning(
'using %s instead of %s'
, name, fn )
129
else
:
130
raise
IncludeError(
'include file %s can not be found'
% fn )
131
132
self.msg.
debug
(
'located %s as %s'
, fn, name )
133
134
# print if 'show' is set to non-null
135
show = self._show
136
if
'show'
in
kw:
137
show = kw[
'show'
]
138
139
# notify of start of file inclusion
140
if
show:
141
self.msg.info(
'including file "%s" with ID %d'
, fn, self.fid )
142
else
:
143
self.msg.info(
'including file "%s"'
, fn )
144
self._fcurrent = name
145
146
# actual inclusion
147
if
show
and
self._doTrace( name ):
148
# traced
149
_filecache[ name ] = open( name,
'r'
).readlines()
150
_linecache[ name ] = 0, self.fid
151
self.fid += 1
152
153
from
past.builtins
import
execfile
154
sys.settrace( self.
_trace_include
)
155
execfile( name, self.
_workspace
, self.
_workspace
)
156
sys.settrace( sys._getframe(0).f_trace )
157
158
# finish file printout
159
ncur, fid = _linecache[ name ]
160
buf = _filecache[ name ]
161
for
i
in
range( ncur, len(buf) ):
162
self.
_oneline
( fid, i, silentMarker, buf )
163
164
del _filecache[ name ]
165
del _linecache[ name ]
166
167
self.
msg
.info(
'end of "%s"'
, fn )
168
169
else
:
170
# non-traced
171
#execfile( name, self._workspace, self._workspace )
172
exec(compile(open(name).
read
(), name,
'exec'
), self.
_workspace
, self.
_workspace
)
173
174
175
if
hasattr( self,
'_collect'
):
176
if
not
self.
_collect
% 10:
177
import
gc
178
gc.collect()
179
else
:
180
self.
_collect
+= 1
181
182
def
block
( self, fn ):
183
"""Disallow the given filename(s) from being included again."""
184
185
if
type
(fn)
is
list:
186
self.
_once
+= fn
187
else
:
188
self.
_once
.append( fn )
189
190
def
unblock
( self, fn ):
191
"""Re-allow the given filename from being included."""
192
193
self.
_once
.remove( fn )
194
195
# match files to trace ------------------------------------------------------
196
def
_doTrace
( self, fn ):
197
# Tracing into non-included files is controlled with two variables:
198
# excludeTracePattern and includeTracePattern. The former goes first,
199
# the latter can override any excluded results.
200
201
if
fn
in
_notrcache:
202
return
False
203
204
doTrace =
True
205
for
tracePattern
in
excludeTracePattern:
206
if
fnmatch.fnmatch( fn, tracePattern ):
207
doTrace =
False
208
break
209
210
if
not
doTrace:
211
for
tracePattern
in
includeTracePattern:
212
if
fnmatch.fnmatch( fn, tracePattern ):
213
doTrace =
True
214
break
215
216
if
not
doTrace:
217
_notrcache[ fn ] = 1
218
219
return
doTrace
220
221
# code tracer ---------------------------------------------------------------
222
def
_trace_include
( self, frame, event, arg ):
223
fn = frame.f_code.co_filename
224
if
fn.find (
'importlib._bootstrap'
) >= 0:
225
return
self.
_trace_include
226
227
if
not
os.path.exists( fn ):
228
fn = FindFile(
basename2
( fn ), sys.path, os.R_OK )
229
230
if
not
( fn
and
self.
_doTrace
( fn ) ):
231
return
self.
_trace_include
232
233
if
fn
not
in
_filecache:
234
# wait until importing of the module is done to minimize pollution
235
f = frame.f_back
236
while
f
is
not
None
:
237
try
:
238
if
'import'
in
_filecache[ f.f_code.co_filename ][ f.f_lineno ]:
239
return
self.
_trace_include
240
except
Exception:
241
pass
242
f = f.f_back
243
del f
244
245
# import is done, and we're back, accept this file from this point on
246
_filecache[ fn ] = open( fn,
'r'
).readlines()
or
'\n'
247
_linecache[ fn ] = sys.maxsize, self.
fid
248
self.
fid
+= 1
249
250
lno = frame.f_lineno
251
aln = lno - 1 > 0
and
lno - 1
or
0
252
253
ncur, fid = _linecache[ fn ]
254
buf = _filecache[ fn ]
255
256
if
self.
_fcurrent
!= fn:
257
self.
msg
.info(
'continued trace of "%s"'
,
basename2
( fn ) )
258
self.
_fcurrent
= fn
259
260
if
event ==
'line'
:
261
for
i
in
range( ncur, aln ):
262
self.
_oneline
( fid, i, silentMarker, buf )
263
264
if
ncur <= aln:
265
self.
_oneline
( fid, aln, activeMarker, buf )
266
elif
0 <= aln:
267
self.
_oneline
( fid, aln, tracedMarker, buf )
268
269
if
ncur < lno:
270
_linecache[ fn ] = lno, fid
271
272
elif
event ==
'call'
:
273
if
lno < ncur:
274
self.
_oneline
( fid, aln, callMarker, buf )
275
276
elif
event ==
'return'
:
277
if
lno < ncur:
278
fln = frame.f_code.co_firstlineno - 1
279
self.
_oneline
( fid, fln, returnMarker,
None
)
280
281
return
self.
_trace_include
282
283
# formatted line printer
284
def
_oneline
( self, fid, lineno, detail, buf ):
285
print
(marker, fidMarker % fid, lineMarker % lineno, detail,)
286
287
try
:
288
289
# simple eol case
290
if
not
buf
or
not
buf[ lineno ]:
291
print
()
292
return
293
294
# in general, an interpreter "line" may be longer than a file line
295
line = buf[ lineno ].rstrip()
296
while
line
and
( line[-1] ==
'('
or
line[-1] ==
'\\'
):
297
# this line appears to have a continuation ...
298
try
:
299
# output traced line
300
print
(line)
301
302
# output continued line
303
lineno += 1
304
print
(marker, fidMarker % fid, lineMarker % lineno, detail,)
305
line = buf[ lineno ].rstrip()
306
except
IndexError:
307
# shouldn't happen; but must mean that the diagnosis above is
308
# wrong and that there is no continuation, keep silent
309
break
310
311
print
(line)
312
313
except
IndexError:
314
log.warning(
'index (%d) out of range while scanning include file %d'
, lineno, fid )
315
316
317
# use this for backward compatibility
318
include =
Include
(show =
False
)
debug
const bool debug
Definition
MakeUncertaintyPlots.cxx:53
print
void print(char *figname, TCanvas *c1)
Definition
TRTCalib_StrawStatusPlots.cxx:26
python.Include.IncludeError
Definition
Include.py:52
python.Include.Include
Definition
Include.py:75
python.Include.Include.unblock
unblock(self, fn)
Definition
Include.py:190
python.Include.Include._once
list _once
Definition
Include.py:80
python.Include.Include.msg
msg
Definition
Include.py:82
python.Include.Include.setClean
setClean(self, clean)
Definition
Include.py:102
python.Include.Include.fid
int fid
Definition
Include.py:76
python.Include.Include._doTrace
_doTrace(self, fn)
Definition
Include.py:196
python.Include.Include._trace_include
_trace_include
Definition
Include.py:154
python.Include.Include.__call__
__call__(self, fn, *args, **kw)
Definition
Include.py:111
python.Include.Include.__init__
__init__(self, show=True, collect=1, clean=False)
Definition
Include.py:78
python.Include.Include.block
block(self, fn)
Definition
Include.py:182
python.Include.Include.setShowIncludes
setShowIncludes(self, show)
Definition
Include.py:93
python.Include.Include._collect
int _collect
Definition
Include.py:91
python.Include.Include.setCollect
setCollect(self, collect)
Definition
Include.py:96
python.Include.Include._show
_show
Definition
Include.py:79
python.Include.Include._fcurrent
str _fcurrent
Definition
Include.py:81
python.Include.Include._workspace
dict _workspace
Definition
Include.py:85
python.Include.Include._oneline
_oneline(self, fid, lineno, detail, buf)
Definition
Include.py:284
python.Include.basename2
basename2(fn)
files inclusion -------------------------------------------------------—
Definition
Include.py:68
read
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
Definition
openCoraCool.cxx:569
type
Generated on
for ATLAS Offline Software by
1.17.0