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."""
10 import os, sys, re, fnmatch
11 from AthenaCommon.Utils.unixtools
import FindFile
15 __author__ =
'Wim Lavrijsen (WLavrijsen@lbl.gov)'
17 __all__ = [
'include',
'marker',
'lineMarker',
'fidMarker',
18 'callMarker',
'returnMarker',
'activeMarker',
'silentMarker',
32 excludeTracePattern = [
33 '*/GaudiPython/*',
'*/GaudiKernel/*',
35 '*/python%d.%d/*' % sys.version_info[:2],
36 '*/python/*/*Conf.py',
37 '*/PyUtils/decorator.py',
38 '*/PyUtils/Decorators.py',
39 '*/PyUtils/Helper*.py',
41 '*importlib._bootstrap*',
45 includeTracePattern = [
'*/AthenaCommon/Bootstrap.py' ]
49 from AthenaCommon
import Logging
50 log = Logging.logging.getLogger(
'Athena' )
58 optionsPathEnv = os.environ[
'JOBOPTSEARCHPATH' ]
60 optionsPathEnv = os.curdir
62 optionsPath = re.split(
',|' + os.pathsep, optionsPathEnv )
64 optionsPath[ optionsPath.index(
'' ) ] =
str(os.curdir)
69 return os.path.join( os.path.basename( os.path.dirname( fn ) ), os.path.basename( fn ) )
78 def __init__( self, show = True, collect = 1, clean = False ):
82 self.
msg = Logging.logging.getLogger(
'Athena' )
97 if collect
and not hasattr( self,
'_collect' ):
99 elif not collect
and hasattr( self,
'_collect' ):
112 """Include <fn> in the current scope by executing it globally."""
115 if isinstance(fn, str)
and len(fn) == 0:
116 raise IncludeError(
"can not 'include' empty filenames")
120 self.msg.
debug(
'file "%s" is blocked; not included', fn )
124 name =
FindFile( os.path.expanduser( os.path.expandvars( fn ) ), optionsPath, os.R_OK )
126 name =
FindFile( os.path.basename( fn ), optionsPath, os.R_OK )
128 self.msg.warning(
'using %s instead of %s', name, fn )
130 raise IncludeError(
'include file %s can not be found' % fn )
132 self.msg.
debug(
'located %s as %s', fn, name )
141 self.msg.
info(
'including file "%s" with ID %d', fn, self.fid )
143 self.msg.
info(
'including file "%s"', fn )
144 self._fcurrent = name
147 if show
and self._doTrace( name ):
149 _filecache[ name ] =
open( name,
'r' ).readlines()
150 _linecache[ name ] = 0, self.fid
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 )
159 ncur, fid = _linecache[ name ]
160 buf = _filecache[ name ]
161 for i
in range( ncur, len(buf) ):
162 self._oneline( fid, i, silentMarker, buf )
164 del _filecache[ name ]
165 del _linecache[ name ]
167 self.msg.
info(
'end of "%s"', fn )
172 exec(compile(
open(name).
read(), name,
'exec'), self._workspace, self._workspace)
175 if hasattr( self,
'_collect' ):
176 if not self._collect % 10:
183 """Disallow the given filename(s) from being included again."""
191 """Re-allow the given filename from being included."""
205 for tracePattern
in excludeTracePattern:
206 if fnmatch.fnmatch( fn, tracePattern ):
211 for tracePattern
in includeTracePattern:
212 if fnmatch.fnmatch( fn, tracePattern ):
223 fn = frame.f_code.co_filename
224 if fn.find (
'importlib._bootstrap') >= 0:
227 if not os.path.exists( fn ):
230 if not ( fn
and self.
_doTrace( fn ) ):
233 if fn
not in _filecache:
238 if 'import' in _filecache[ f.f_code.co_filename ][ f.f_lineno ]:
246 _filecache[ fn ] =
open( fn,
'r' ).readlines()
or '\n'
247 _linecache[ fn ] = sys.maxsize, self.
fid
251 aln = lno - 1 > 0
and lno - 1
or 0
253 ncur, fid = _linecache[ fn ]
254 buf = _filecache[ fn ]
261 for i
in range( ncur, aln ):
262 self.
_oneline( fid, i, silentMarker, buf )
265 self.
_oneline( fid, aln, activeMarker, buf )
267 self.
_oneline( fid, aln, tracedMarker, buf )
270 _linecache[ fn ] = lno, fid
272 elif event ==
'call':
274 self.
_oneline( fid, aln, callMarker, buf )
276 elif event ==
'return':
278 fln = frame.f_code.co_firstlineno - 1
279 self.
_oneline( fid, fln, returnMarker,
None )
285 print (marker, fidMarker % fid, lineMarker % lineno, detail,)
290 if not buf
or not buf[ lineno ]:
295 line = buf[ lineno ].rstrip()
296 while line
and ( line[-1] ==
'(' or line[-1] ==
'\\' ):
304 print (marker, fidMarker % fid, lineMarker % lineno, detail,)
305 line = buf[ lineno ].rstrip()
314 log.warning(
'index (%d) out of range while scanning include file %d', lineno, fid )