Gaudi Framework, version v23r6

Home   Generated: Wed Jan 30 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Variable.py
Go to the documentation of this file.
1 '''
2 Created on Jun 27, 2011
3 
4 @author: mplajner
5 '''
6 import re
7 import os
8 from os.path import normpath
9 from zipfile import is_zipfile
10 
11 class VariableProcessor(object):
12  '''
13  Base class for the objects used to process the variables.
14  '''
15  def __init__(self, env):
16  '''
17  @param env: dictionary with the reference environment to use
18  '''
19  if env is None:
20  env = {}
21  self._env = env
22 
23  def isTarget(self, variable):
24  '''
25  Return True if this processor can operate on the given variable.
26  '''
27  return True
28 
29  def process(self, variable, value):
30  '''
31  Process the variable.
32 
33  @param value: the content of the variable to be processed
34  @return: the processed value
35  '''
36  # by default do nothing
37  return value
38 
39  def __call__(self, variable, value):
40  return self.process(variable, value)
41 
43  '''
44  Base class for processors operating only on lists.
45  '''
46  def isTarget(self, variable):
47  '''
48  Return True if this variable is a list.
49  '''
50  return isinstance(variable, List)
51 
53  '''
54  Base class for processors operating only on scalars.
55  '''
56  def isTarget(self, variable):
57  '''
58  Return True if this variable is a scalar.
59  '''
60  return isinstance(variable, Scalar)
61 
63  '''
64  Variable processor to expand the reference to environment variables.
65  '''
66  def __init__(self, env):
67  super(EnvExpander, self).__init__(env)
68  self._exp = re.compile(r"\$([A-Za-z_][A-Za-z0-9_]*)|\$\(([A-Za-z_][A-Za-z0-9_]*)\)|\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$\{(\.)\}")
69 
70  def isTarget(self, variable):
71  return (super(EnvExpander, self).isTarget(variable)
72  and variable.expandVars)
73 
74  def _repl(self, value):
75  m = self._exp.search(value)
76  if m:
77  value = (value[:m.start()]
78  + str(self._env[filter(None, m.groups())[0]])
79  + value[m.end():])
80  return self._repl(value)
81  else:
82  return value
83 
84  def process(self, variable, value):
85  if isinstance(value, str):
86  value = self._repl(value)
87  else:
88  # expand only in the elements that are new
89  old_values = set(variable.val)
90  value = map(lambda v: v if v in old_values else self._repl(v), value)
91  return value
92 
94  '''
95  Call os.path.normpath for all the entries of the variable.
96  '''
97  def process(self, variable, value):
98  if isinstance(value, str):
99  if '://' not in value: # this might be a URL
100  value = normpath(value)
101  else:
102  value = [normpath(v) for v in value if v]
103  return value
104 
106  '''
107  Remove duplicates entries from lists.
108  '''
109  def process(self, variable, value):
110  val = []
111  for s in value:
112  if s not in val:
113  val.append(s)
114  return val
115 
117  '''
118  Remove empty or not existing directories from lists.
119  '''
120  def process(self, variable, value):
121  from os.path import isdir
122  from os import listdir
123  return [s for s in value if s.endswith('.zip') or (isdir(s) and listdir(s))]
124 
126  '''
127  Use .zip files instead of regular directories in PYTHONPATH when possible.
128  '''
129  def isTarget(self, variable):
130  return (super(UsePythonZip, self).isTarget(variable)
131  and variable.varName == 'PYTHONPATH')
132 
133  def process(self, variable, value):
134  val = []
135  for s in value:
136  z = s + '.zip'
137  if is_zipfile(z):
138  val.append(z)
139  else:
140  val.append(s)
141  return val
142 
143 # Default (minimal) set of processors.
144 processors = [ EnvExpander, PathNormalizer, DuplicatesRemover,
145  # special processors
146  EmptyDirsRemover, UsePythonZip
147  ]
148 
149 # FIXME: these are back-ward compatibility hacks: we need a proper way to add/remove processors
150 if ('no-strip-path' in os.environ.get('CMTEXTRATAGS', '')
151  or 'GAUDI_NO_STRIP_PATH' in os.environ
152  or 'LB_NO_STRIP_PATH' in os.environ):
153  processors.remove(EmptyDirsRemover)
154 
155 if 'no-pyzip' in os.environ.get('CMTEXTRATAGS', ''):
156  processors.remove(UsePythonZip)
157 
158 class VariableBase(object):
159  '''
160  Base class for the classes used to manipulate the environment.
161  '''
162 
163  def __init__(self, name, local=False, report=None):
164  self.report = report
165  self.varName = name
166  self.local = local
167  self.expandVars = True
168 
169  def process(self, value, env):
170  '''
171  Call all the processors defined in the processors list on 'value'.
172 
173  @return: the processed value
174  '''
175  for p in [c(env) for c in processors]:
176  if p.isTarget(self):
177  value = p(self, value)
178  return value
179 
181  '''
182  Class for manipulating with environment lists.
183 
184  It holds its name and values represented by a list.
185  Some operations are done with separator, which is usually colon. For windows use semicolon.
186  '''
187 
188  def __init__(self, name, local=False, report=None):
189  super(List, self).__init__(name, local, report)
190  self.val = []
191 
192  def name(self):
193  '''Returns the name of the List.'''
194  return self.varName
195 
196  def set(self, value, separator=':', environment=None):
197  '''Sets the value of the List. Any previous value is overwritten.'''
198  if isinstance(value, str):
199  value = value.split(separator)
200  self.val = self.process(value, environment)
201 
202  def unset(self, value, separator=':', environment=None):# pylint: disable=W0613
203  '''Sets the value of the List to empty. Any previous value is overwritten.'''
204  self.val = []
205 
206  def value(self, asString=False, separator=':'):
207  '''Returns values of the List. Either as a list or string with desired separator.'''
208  if asString:
209  return separator.join(self.val)
210  else:
211  # clone the list
212  return list(self.val)
213 
214  def remove_regexp(self, value, separator = ':'):
215  self.remove(value, separator, True)
216 
217  def remove(self, value, separator=':', regexp=False):
218  '''Removes value(s) from List. If value is not found, removal is canceled.'''
219  if regexp:
220  value = self.search(value, True)
221 
222  elif isinstance(value,str):
223  value = value.split(separator)
224 
225  for i in range(len(value)):
226  val = value[i]
227  if val not in value:
228  self.report.addWarn('Value "'+val+'" not found in List: "'+self.varName+'". Removal canceled.')
229  while val in self.val:
230  self.val.remove(val)
231 
232 
233  def append(self, value, separator=':', environment=None):
234  '''Adds value(s) at the end of the list.'''
235  if isinstance(value, str):
236  value = value.split(separator)
237  self.val = self.process(self.val + value, environment)
238 
239  def prepend(self, value, separator=':', environment=None):
240  '''Adds value(s) at the beginning of the list.
241  resolve references and duplications'''
242  if isinstance(value, str):
243  value = value.split(separator)
244  self.val = self.process(value + self.val, environment)
245 
246  def search(self, expr, regExp):
247  '''Searches in List's values for a match
248 
249  Use string value or set regExp to True.
250  In the first case search is done only for an exact match for one of List`s value ('^' and '$' added).
251  '''
252  if not regExp:
253  expr = '^' + expr + '$'
254  v = re.compile(expr)
255  res = []
256  for val in self.val:
257  if v.search(val):
258  res.append(val)
259 
260  return res
261 
262  def __getitem__(self, key):
263  return self.val[key]
264 
265  def __setitem__(self, key, value):
266  if value in self.val:
267  self.report.addWarn('Var: "' + self.varName + '" value: "' + value + '". Addition canceled because of duplicate entry.')
268  else:
269  self.val.insert(key, value)
270 
271  def __delitem__(self, key):
272  self.remove(self.val[key])
273 
274  def __iter__(self):
275  for i in self.val:
276  yield i
277 
278  def __contains__(self, item):
279  return item in self.val
280 
281  def __len__(self):
282  return len(self.val)
283 
284  def __str__(self):
285  return ':'.join(self.val)
286 
287 
289  '''Class for manipulating with environment scalars.'''
290 
291  def __init__(self, name, local=False, report=None):
292  super(Scalar, self).__init__(name, local, report)
293  self.val = ''
294 
295  def name(self):
296  '''Returns the name of the scalar.'''
297  return self.varName
298 
299  def set(self, value, separator=':', environment=None):# pylint: disable=W0613
300  '''Sets the value of the scalar. Any previous value is overwritten.'''
301  self.val = self.process(value, environment)
302 
303  def unset(self, value, separator=':', environment=None):# pylint: disable=W0613
304  '''Sets the value of the variable to empty. Any previous value is overwritten.'''
305  self.val = ''
306 
307  def value(self, asString=False, separator=':'):# pylint: disable=W0613
308  '''Returns values of the scalar.'''
309  return self.val
310 
311  def remove_regexp(self, value, separator=':'):
312  self.remove(value, separator, True)
313 
314  def remove(self, value, separator=':', regexp=True):# pylint: disable=W0613
315  '''Removes value(s) from the scalar. If value is not found, removal is canceled.'''
316  value = self.search(value)
317  for val in value:
318  self.val = self.val.replace(val, '')
319 
320  def append(self, value, separator=':', environment=None):# pylint: disable=W0613
321  '''Adds value(s) at the end of the scalar.'''
322  self.val += self.process(value, environment)
323 
324  def prepend(self, value, separator=':', environment=None):# pylint: disable=W0613
325  '''Adds value(s) at the beginning of the scalar.'''
326  self.val = self.process(value, environment) + self.val
327 
328  def search(self, expr):
329  '''Searches in scalar`s values for a match'''
330  return re.findall(expr, self.val)
331 
332  def __str__(self):
333  return self.val
334 
335 class EnvError(Exception):
336  '''Class which defines errors for locals operations.'''
337  def __init__(self, value, code):
338  super(EnvError, self).__init__()
339  self.val = value
340  self.code = code
341  def __str__(self):
342  if self.code == 'undefined':
343  return 'Reference to undefined environment element: "'+self.val +'".'
344  elif self.code == 'ref2var':
345  return 'Reference to list from the middle of string.'
346  elif self.code == 'redeclaration':
347  return 'Wrong redeclaration of environment element "'+self.val+'".'

Generated at Wed Jan 30 2013 17:13:37 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004