LSSTApplications  20.0.0
LSSTDataManagementBasePackage
Classes | Functions | Variables
base.packages Namespace Reference

Classes

class  Packages
 

Functions

def getVersionFromPythonModule (module)
 
def getPythonPackages ()
 
def getEnvironmentPackages ()
 

Variables

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

Function Documentation

◆ getEnvironmentPackages()

def 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 145 of file packages.py.

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

◆ getPythonPackages()

def 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 87 of file packages.py.

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

◆ getVersionFromPythonModule()

def 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 52 of file packages.py.

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

Variable Documentation

◆ BUILDTIME

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

Definition at line 41 of file packages.py.

◆ ENVIRONMENT

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

Definition at line 49 of file packages.py.

◆ log

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

Definition at line 35 of file packages.py.

◆ PYTHON

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

Definition at line 45 of file packages.py.

base.packages.getPythonPackages
def getPythonPackages()
Definition: packages.py:87
strip
bool strip
Definition: fits.cc:911
base.packages.getVersionFromPythonModule
def getVersionFromPythonModule(module)
Definition: packages.py:52
list
daf::base::PropertyList * list
Definition: fits.cc:913
base.packages.getEnvironmentPackages
def getEnvironmentPackages()
Definition: packages.py:145
set
daf::base::PropertySet * set
Definition: fits.cc:912