LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
repositoryCfg.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 # LSST Data Management System
5 # Copyright 2016 LSST Corporation.
6 #
7 # This product includes software developed by the
8 # LSST Project (http://www.lsst.org/).
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the LSST License Statement and
21 # the GNU General Public License along with this program. If not,
22 # see <http://www.lsstcorp.org/LegalNotices/>.
23 #
24 
25 # -*- python -*-
26 
27 import inspect
28 import yaml
29 
30 from lsst.daf.persistence import listify, iterify
31 
32 
33 class RepositoryCfg(yaml.YAMLObject):
34  yaml_tag = u"!RepositoryCfg_v1"
35 
36  def __init__(self, root, mapper, mapperArgs, parents, isLegacyRepository=False):
37  self._root = root
38  self._mapper = mapper
39  self._mapperArgs = mapperArgs
40  self._parents = iterify(parents)
41  self._isLegacyRepository = isLegacyRepository
42 
43  @staticmethod
44  def v1Constructor(loader, node):
45  """Constructor for 'version 1' of the serlized RepositoryCfg.
46 
47  If new parameters are added to RepositoryCfg they will have to be checked for in d; if they are there
48  then their value should be used and if they are not there a default value must be used in place.
49 
50  In case the structure of the serialzed file must be changed in a way that invalidates some of the
51  keys:
52  1. Increment the version number (after _v1) in the yaml_tag of this class.
53  2. Add a new constructor (similar to this one) to deserialze new serializations of this class.
54  3. Registered the new constructor for the new version with yaml, the same way it is done at the bottom
55  of this file.
56  4. All constructors for the older version(s) of persisted RepositoryCfg must be changed to adapt
57  the old keys to their new uses and create the current (new) version of a repository cfg, or raise a
58  RuntimeError in the case that older versions of serialized RepositoryCfgs can not be adapted.
59  There is an example of migrating from a fictitious v0 to v1 in tests/repositoryCfg.py
60  """
61  d = loader.construct_mapping(node)
62  cfg = RepositoryCfg(root=d['_root'], mapper=d['_mapper'], mapperArgs=d['_mapperArgs'],
63  parents=d['_parents'], isLegacyRepository=d['_isLegacyRepository'])
64  return cfg
65 
66  def __eq__(self, other):
67  if not other:
68  return False
69  return self._root == other._root and \
70  self.mapper == other._mapper and \
71  self.mapperArgs == other._mapperArgs and \
72  self.parents == other._parents and \
73  self._isLegacyRepository == other._isLegacyRepository
74 
75  def __ne__(self, other):
76  return not self.__eq__(other)
77 
78  @property
79  def root(self):
80  return self._root
81 
82  @root.setter
83  def root(self, root):
84  if root is not None and self._root is not None:
85  raise RuntimeError("Explicity clear root (set to None) before changing the value of root.")
86  self._root = root
87 
88  @property
89  def mapper(self):
90  return self._mapper
91 
92  @property
93  def mapperArgs(self):
94  return self._mapperArgs
95 
96  @mapperArgs.setter
97  def mapperArgs(self, newDict):
98  self._mapperArgs = newDict
99 
100  @property
101  def parents(self):
102  return self._parents
103 
104  def addParents(self, newParents):
105  newParents = listify(newParents)
106  for newParent in newParents:
107  if newParent not in self._parents:
108  self._parents.append(newParent)
109 
110  @property
112  return self._isLegacyRepository
113 
114  @staticmethod
115  def makeFromArgs(repositoryArgs, parents):
116  cfg = RepositoryCfg(root=repositoryArgs.root,
117  mapper=repositoryArgs.mapper,
118  mapperArgs=repositoryArgs.mapperArgs,
119  parents=parents,
120  isLegacyRepository=repositoryArgs.isLegacyRepository)
121  return cfg
122 
123  def matchesArgs(self, repositoryArgs):
124  if repositoryArgs.root is not None and self._root != repositoryArgs.root:
125  return False
126  if repositoryArgs.mapper is not None:
127  if inspect.isclass(self._mapper):
128  if not inspect.isclass(repositoryArgs.mapper):
129  return False
130  if self._mapper != repositoryArgs.mapper:
131  return False
132  else:
133  if type(self._mapper) != type(repositoryArgs.mapper):
134  return False
135  # check mapperArgs for any keys in common and if their value does not match then return false.
136  if self._mapperArgs is not None and repositoryArgs.mapperArgs is not None:
137  for key in set(self._mapperArgs.keys()) & set(repositoryArgs.mapperArgs):
138  if self._mapperArgs[key] != repositoryArgs.mapperArgs[key]:
139  return False
140  return True
141 
142  def __repr__(self):
143  return "%s(root=%r, mapper=%r, mapperArgs=%r, parents=%s, isLegacyRepository=%s)" % (
144  self.__class__.__name__,
145  self._root,
146  self._mapper,
147  self._mapperArgs,
148  self._parents,
149  self._isLegacyRepository)
150 
151 yaml.add_constructor(u"!RepositoryCfg_v1", RepositoryCfg.v1Constructor)