LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Classes | Functions | Variables
lsst.base.packages Namespace Reference

Classes

class  Packages
 

Functions

def getVersionFromPythonModule (module)
 
def getPythonPackages ()
 
def getEnvironmentPackages ()
 
def getCondaPackages ()
 
def pkg_representer (dumper, data)
 
def pkg_constructor (loader, node)
 

Variables

 log = logging.getLogger(__name__)
 
 BUILDTIME = set(["boost", "eigen", "tmv"])
 
 PYTHON = set(["galsim"])
 
 ENVIRONMENT = set(["astrometry_net", "astrometry_net_data", "minuit2", "xpa"])
 
 pkg_constructor
 
 Loader
 

Function Documentation

◆ getCondaPackages()

def lsst.base.packages.getCondaPackages ( )
Get products and their versions from the conda environment.

Returns
-------
packages : `dict`
    Keys (type `str`) are product names; values (type `str`) are their
    versions.

Notes
-----
Returns empty result if a conda environment is not in use or can not
be queried.

Definition at line 223 of file packages.py.

223 def getCondaPackages():
224  """Get products and their versions from the conda environment.
225 
226  Returns
227  -------
228  packages : `dict`
229  Keys (type `str`) are product names; values (type `str`) are their
230  versions.
231 
232  Notes
233  -----
234  Returns empty result if a conda environment is not in use or can not
235  be queried.
236  """
237 
238  try:
239  import json
240  from conda.cli.python_api import Commands, run_command
241  except ImportError:
242  return {}
243 
244  # Get the installed package list
245  versions_json = run_command(Commands.LIST, "--json")
246  packages = {pkg["name"]: pkg["version"] for pkg in json.loads(versions_json[0])}
247 
248  # Try to work out the conda environment name and include it as a fake
249  # package. The "obvious" way of running "conda info --json" does give
250  # access to the active_prefix but takes about 2 seconds to run.
251  # The equivalent to the code above would be:
252  # info_json = run_command(Commands.INFO, "--json")
253  # As a comporomise look for the env name in the path to the python
254  # executable
255  match = re.search(r"/envs/(.*?)/bin/", sys.executable)
256  if match:
257  packages["conda_env"] = match.group(1)
258 
259  return packages
260 
261 
def getCondaPackages()
Definition: packages.py:223

◆ getEnvironmentPackages()

def lsst.base.packages.getEnvironmentPackages ( )
Get products and their versions from the environment.

Returns
-------
packages : `dict`
    Keys (type `str`) are product names; values (type `str`) are their
    versions.

Notes
-----
We use EUPS to determine the version of certain products (those that don't
provide a means to determine the version any other way) and to check if
uninstalled packages are being used. We only report the product/version
for these packages.

Definition at line 154 of file packages.py.

155  """Get products and their versions from the environment.
156 
157  Returns
158  -------
159  packages : `dict`
160  Keys (type `str`) are product names; values (type `str`) are their
161  versions.
162 
163  Notes
164  -----
165  We use EUPS to determine the version of certain products (those that don't
166  provide a means to determine the version any other way) and to check if
167  uninstalled packages are being used. We only report the product/version
168  for these packages.
169  """
170  try:
171  from eups import Eups
172  from eups.Product import Product
173  except ImportError:
174  log.warning("Unable to import eups, so cannot determine package versions from environment")
175  return {}
176 
177  # Cache eups object since creating it can take a while
178  global _eups
179  if not _eups:
180  _eups = Eups()
181  products = _eups.findProducts(tags=["setup"])
182 
183  # Get versions for things we can't determine via runtime mechanisms
184  # XXX Should we just grab everything we can, rather than just a
185  # predetermined set?
186  packages = {prod.name: prod.version for prod in products if prod in ENVIRONMENT}
187 
188  # The string 'LOCAL:' (the value of Product.LocalVersionPrefix) in the
189  # version name indicates uninstalled code, so the version could be
190  # different than what's being reported by the runtime environment (because
191  # we don't tend to run "scons" every time we update some python file,
192  # and even if we did sconsUtils probably doesn't check to see if the repo
193  # is clean).
194  for prod in products:
195  if not prod.version.startswith(Product.LocalVersionPrefix):
196  continue
197  ver = prod.version
198 
199  gitDir = os.path.join(prod.dir, ".git")
200  if os.path.exists(gitDir):
201  # get the git revision and an indication if the working copy is
202  # clean
203  revCmd = ["git", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "rev-parse", "HEAD"]
204  diffCmd = ["git", "--no-pager", "--git-dir=" + gitDir, "--work-tree=" + prod.dir, "diff",
205  "--patch"]
206  try:
207  rev = subprocess.check_output(revCmd).decode().strip()
208  diff = subprocess.check_output(diffCmd)
209  except Exception:
210  ver += "@GIT_ERROR"
211  else:
212  ver += "@" + rev
213  if diff:
214  ver += "+" + hashlib.md5(diff).hexdigest()
215  else:
216  ver += "@NO_GIT"
217 
218  packages[prod.name] = ver
219  return packages
220 
221 
222 @lru_cache(maxsize=1)
bool strip
Definition: fits.cc:911
def getEnvironmentPackages()
Definition: packages.py:154

◆ getPythonPackages()

def lsst.base.packages.getPythonPackages ( )
Get imported python packages and their versions.

Returns
-------
packages : `dict`
    Keys (type `str`) are package names; values (type `str`) are their
    versions.

Notes
-----
We wade through `sys.modules` and attempt to determine the version for each
module.  Note, therefore, that we can only report on modules that have
*already* been imported.

We don't include any module for which we cannot determine a version.

Definition at line 92 of file packages.py.

92 def getPythonPackages():
93  """Get imported python packages and their versions.
94 
95  Returns
96  -------
97  packages : `dict`
98  Keys (type `str`) are package names; values (type `str`) are their
99  versions.
100 
101  Notes
102  -----
103  We wade through `sys.modules` and attempt to determine the version for each
104  module. Note, therefore, that we can only report on modules that have
105  *already* been imported.
106 
107  We don't include any module for which we cannot determine a version.
108  """
109  # Attempt to import libraries that only report their version in python
110  for module in PYTHON:
111  try:
112  importlib.import_module(module)
113  except Exception:
114  pass # It's not available, so don't care
115 
116  packages = {"python": sys.version}
117  # Not iterating with sys.modules.iteritems() because it's not atomic and
118  # subject to race conditions
119  moduleNames = list(sys.modules.keys())
120  for name in moduleNames:
121  module = sys.modules[name]
122  try:
123  ver = getVersionFromPythonModule(module)
124  except Exception:
125  continue # Can't get a version from it, don't care
126 
127  # Remove "foo.bar.version" in favor of "foo.bar"
128  # This prevents duplication when the __init__.py includes
129  # "from .version import *"
130  for ending in (".version", "._version"):
131  if name.endswith(ending):
132  name = name[:-len(ending)]
133  if name in packages:
134  assert ver == packages[name]
135  elif name in packages:
136  assert ver == packages[name]
137 
138  # Use LSST package names instead of python module names
139  # This matches the names we get from the environment (i.e., EUPS)
140  # so we can clobber these build-time versions if the environment
141  # reveals that we're not using the packages as-built.
142  if "lsst" in name:
143  name = name.replace("lsst.", "").replace(".", "_")
144 
145  packages[name] = ver
146 
147  return packages
148 
149 
daf::base::PropertyList * list
Definition: fits.cc:913
def getPythonPackages()
Definition: packages.py:92
def getVersionFromPythonModule(module)
Definition: packages.py:57

◆ getVersionFromPythonModule()

def lsst.base.packages.getVersionFromPythonModule (   module)
Determine the version of a python module.

Parameters
----------
module : `module`
    Module for which to get version.

Returns
-------
version : `str`

Raises
------
AttributeError
    Raised if __version__ attribute is not set.

Notes
-----
We supplement the version with information from the
``__dependency_versions__`` (a specific variable set by LSST's
`~lsst.sconsUtils` at build time) only for packages that are typically
used only at build-time.

Definition at line 57 of file packages.py.

57 def getVersionFromPythonModule(module):
58  """Determine the version of a python module.
59 
60  Parameters
61  ----------
62  module : `module`
63  Module for which to get version.
64 
65  Returns
66  -------
67  version : `str`
68 
69  Raises
70  ------
71  AttributeError
72  Raised if __version__ attribute is not set.
73 
74  Notes
75  -----
76  We supplement the version with information from the
77  ``__dependency_versions__`` (a specific variable set by LSST's
78  `~lsst.sconsUtils` at build time) only for packages that are typically
79  used only at build-time.
80  """
81  version = module.__version__
82  if hasattr(module, "__dependency_versions__"):
83  # Add build-time dependencies
84  deps = module.__dependency_versions__
85  buildtime = BUILDTIME & set(deps.keys())
86  if buildtime:
87  version += " with " + " ".join("%s=%s" % (pkg, deps[pkg])
88  for pkg in sorted(buildtime))
89  return str(version)
90 
91 
daf::base::PropertySet * set
Definition: fits.cc:912

◆ pkg_constructor()

def lsst.base.packages.pkg_constructor (   loader,
  node 
)

Definition at line 527 of file packages.py.

527 def pkg_constructor(loader, node):
528  yield Packages(loader.construct_mapping(node, deep=True))
529 
530 
def pkg_constructor(loader, node)
Definition: packages.py:527

◆ pkg_representer()

def lsst.base.packages.pkg_representer (   dumper,
  data 
)
Represent Packages as a simple dict

Definition at line 518 of file packages.py.

518 def pkg_representer(dumper, data):
519  """Represent Packages as a simple dict"""
520  return dumper.represent_mapping("lsst.base.Packages", data._packages,
521  flow_style=None)
522 
523 
524 yaml.add_representer(Packages, pkg_representer)
525 
526 
def pkg_representer(dumper, data)
Definition: packages.py:518

Variable Documentation

◆ BUILDTIME

lsst.base.packages.BUILDTIME = set(["boost", "eigen", "tmv"])

Definition at line 45 of file packages.py.

◆ ENVIRONMENT

lsst.base.packages.ENVIRONMENT = set(["astrometry_net", "astrometry_net_data", "minuit2", "xpa"])

Definition at line 54 of file packages.py.

◆ Loader

lsst.base.packages.Loader

Definition at line 532 of file packages.py.

◆ log

lsst.base.packages.log = logging.getLogger(__name__)

Definition at line 38 of file packages.py.

◆ pkg_constructor

lsst.base.packages.pkg_constructor

Definition at line 532 of file packages.py.

◆ PYTHON

lsst.base.packages.PYTHON = set(["galsim"])

Definition at line 50 of file packages.py.