CMS 3D CMS Logo

findAndChange.py
Go to the documentation of this file.
1 import os
2 from FWCore.ParameterSet.pfnInPath import pfnInPath
3 
4 
5 def digest_path(path):
6 
7  """ Ensure that everything is done for path to exist
8  Arguments:
9  - path: String that can be both directory and file
10  Return:
11  - general: environmental variables are expanded
12  - directory: is checked to exist
13  - file: is checked to exist with backup directory being searched in cms-data
14  """
15  # sanity check for string argument
16  if not isinstance(path, str):
17  return path
18 
19  # split path in folders
20  protocol = ""
21  if "://" in path:
22  protocol = path.split("://")[0]+"://"
23  path_s = path.split("://")[1].split(os.sep)
24  else:
25  path_s = path.split(os.sep)
26 
27  path_d_s = []
28  placeholderIdx = []
29  for ipart,part in enumerate(path_s):
30  # Look for environment variables such as $CMSSW_BASE
31  if part.startswith('$'):
32  env_var = part[1:].replace('{', '').replace('}', '')
33  path_d_s.append(os.environ[env_var])
34  # Look for {} placeholder to be replaced internally
35  elif "{}" in part:
36  placeholderIdx.append(ipart)
37  path_d_s.append(part)
38  else:
39  path_d_s.append(part)
40 
41  # re-join folders into full path
42  # only check path up to first placeholder occurence
43  path_d = os.path.join(*path_d_s)
44  if len(placeholderIdx) > 0:
45  path_to_check = os.path.join(*path_d_s[:placeholderIdx[0]])
46  else:
47  path_to_check = path_d
48 
49  # re add front / if needed
50  if path.startswith(os.sep):
51  path_d = os.sep + path_d
52  path_to_check = os.sep + path_to_check
53 
54  # check for path to exist
55  if not os.path.exists(path_to_check) and "." in os.path.splitext(path_to_check)[-1]:
56  # in case of directory pointing to file try backup
57  _file = pfnInPath(path_to_check)
58  if "file:" in _file:
59  return _file.split(":")[-1]
60 
61  # re add protocol declaration
62  if protocol != "": path_d = protocol + path_d
63 
64  # if all is OK return path to directory or file
65  return path_d
66 
67 
68 def get_all_keys(var):
69 
70  """
71  Generate all keys for nested dictionary
72  """
73  if hasattr(var,'items'):
74  for k, v in var.items():
75  if isinstance(v, dict):
76  for result in get_all_keys(v):
77  yield result
78  elif isinstance(v, list):
79  for d in v:
80  for result in get_all_keys(d):
81  yield result
82  else:
83  yield k
84 
85 
86 def find_and_change(keys, var, alt=digest_path):
87 
88  """Perform effective search for keys in nested dictionary
89  - if key is found, corresponding value is "digested"
90  - generator is returned for printout purpose only
91  - original var is overwritten
92  """
93  if hasattr(var,'items'):
94  if len(keys) == 0:
95  for key in get_all_keys(var):
96  keys.append(key)
97  for key in keys:
98  for k, v in var.items():
99  if k == key:
100  if isinstance(v,list):
101  var[k] = [alt(_v) for _v in v]
102  else:
103  var[k] = alt(v)
104  yield alt(v)
105  if isinstance(v, dict):
106  for result in find_and_change([key], v):
107  yield result
108  elif isinstance(v, list):
109  for d in v:
110  for result in find_and_change([key], d):
111  yield result
def find_and_change(keys, var, alt=digest_path)
def replace(string, replacements)
def digest_path(path)
Definition: findAndChange.py:5
def get_all_keys(var)