28 """Helper functions for comparing `lsst.pex.config.Config` instancess. 
   30 Theses function should be use for any comparison in a `lsst.pex.Config.compare` 
   31 or `lsst.pex.config.Field._compare` implementation, as they take care of 
   32 writing messages as well as floating-point comparisons and shortcuts. 
   35 __all__ = (
"getComparisonName", 
"compareScalars", 
"compareConfigs")
 
   41     """Create a comparison name that is used for printed output of comparisons. 
   46         Name of the first configuration. 
   48         Name of the second configuration. 
   53         When ``name1`` and ``name2`` are equal, the returned name is 
   54         simply one of the names. When they are different the returned name is 
   55         formatted as ``"{name1} / {name2}"``. 
   58         return "%s / %s" % (name1, name2)
 
   63     """Compare two scalar values for equality. 
   65     This function is a helper for `lsst.pex.config.Config.compare`. 
   70         Name to use when reporting differences, typically created by 
   73         Left-hand side value to compare. 
   75         Right-hand side value to compare. 
   76     output : callable or `None` 
   77         A callable that takes a string, used (possibly repeatedly) to report 
   78         inequalities (for example, `print`). Set to `None` to disable output. 
   79     rtol : `float`, optional 
   80         Relative tolerance for floating point comparisons. 
   81     atol : `float`, optional 
   82         Absolute tolerance for floating point comparisons. 
   83     dtype : class, optional 
   84         Data type of values for comparison. May be `None` if values are not 
   90         `True` if the values are equal, `False` if they are not. 
   94     lsst.pex.config.compareConfigs 
   98     Floating point comparisons are performed by `numpy.allclose`. 
  100     if v1 
is None or v2 
is None:
 
  102     elif dtype 
in (float, complex):
 
  103         result = numpy.allclose(v1, v2, rtol=rtol, atol=atol) 
or (numpy.isnan(v1) 
and numpy.isnan(v2))
 
  106     if not result 
and output 
is not None:
 
  107         output(
"Inequality in %s: %r != %r" % (name, v1, v2))
 
  111 def compareConfigs(name, c1, c2, shortcut=True, rtol=1E-8, atol=1E-8, output=None):
 
  112     """Compare two `lsst.pex.config.Config` instances for equality. 
  114     This function is a helper for `lsst.pex.config.Config.compare`. 
  119         Name to use when reporting differences, typically created by 
  121     v1 : `lsst.pex.config.Config` 
  122         Left-hand side config to compare. 
  123     v2 : `lsst.pex.config.Config` 
  124         Right-hand side config to compare. 
  125     shortcut : `bool`, optional 
  126         If `True`, return as soon as an inequality is found. Default is `True`. 
  127     rtol : `float`, optional 
  128         Relative tolerance for floating point comparisons. 
  129     atol : `float`, optional 
  130         Absolute tolerance for floating point comparisons. 
  131     output : callable, optional 
  132         A callable that takes a string, used (possibly repeatedly) to report 
  133         inequalities. For example: `print`. 
  138         `True` when the two `lsst.pex.config.Config` instances are equal. 
  139         `False` if there is an inequality. 
  143     lsst.pex.config.compareScalars 
  147     Floating point comparisons are performed by `numpy.allclose`. 
  149     If ``c1`` or ``c2`` contain `~lsst.pex.config.RegistryField` or 
  150     `~lsst.pex.config.ConfigChoiceField` instances, *unselected* 
  151     `~lsst.pex.config.Config` instances will not be compared. 
  153     assert name 
is not None 
  158             if output 
is not None:
 
  159                 output(
"LHS is None for %s" % name)
 
  163             if output 
is not None:
 
  164                 output(
"RHS is None for %s" % name)
 
  167         if output 
is not None:
 
  168             output(
"Config types do not match for %s: %s != %s" % (name, 
type(c1), 
type(c2)))
 
  171     for field 
in c1._fields.values():
 
  172         result = field._compare(c1, c2, shortcut=shortcut, rtol=rtol, atol=atol, output=output)
 
  173         if not result 
and shortcut:
 
  175         equal = equal 
and result