Skip to content

Commit

Permalink
Merge branch 'main' into issue-3127
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiirola authored Jul 8, 2024
2 parents a5bc693 + 53d5cad commit 072c2c5
Show file tree
Hide file tree
Showing 19 changed files with 1,488 additions and 85 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/test_pr_and_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ jobs:
verbose: true
# How many times to retry a failed request (defaults to 1)
retry_count: 3
# Exclude Jenkins because it's behind a firewall; ignore RTD because
# a magically-generated string is triggering a failure
# Exclude:
# - Jenkins because it's behind a firewall
# - RTD because a magically-generated string triggers failures
exclude_urls: https://pyomo-jenkins.sandia.gov/,https://pyomo.readthedocs.io/en/%s/errors.html


Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ caf = "caf"
WRONLY = "WRONLY"
# Ignore the name Hax
Hax = "Hax"
# Ignore dout (short for dual output in SAS solvers)
dout = "dout"
# Big Sur
Sur = "Sur"
# contrib package named mis and the acronym whence the name comes
Expand Down Expand Up @@ -67,4 +69,6 @@ RO = "RO"
EOF = "EOF"
# Ignore lst as shorthand for list
lst = "lst"
# Abbreviation of gamma (used in stochpdegas1_automatic.py)
gam = "gam"
# AS NEEDED: Add More Words Below
33 changes: 21 additions & 12 deletions .jenkins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
#
# CODECOV_TOKEN: the token to use when uploading results to codecov.io
#
# CODECOV_ARGS: additional arguments to pass to the codecov uploader
# (e.g., to support SSL certificates)
# CODECOV_SOURCE_BRANCH: passed to the 'codecov-cli' command; branch of Pyomo
# (e.g., to enable correct codecov uploads)
#
# CODECOV_REPO_OWNER: passed to the 'codecov-cli' command; owner of repo
# (e.g., to enable correct codecov uploads)
#
# DISABLE_COVERAGE: if nonempty, then coverage analysis is disabled
#
Expand Down Expand Up @@ -202,22 +205,28 @@ if test -z "$MODE" -o "$MODE" == test; then
# Note, that the PWD should still be $WORKSPACE/pyomo
#
coverage combine || exit 1
coverage report -i
coverage report -i || exit 1
coverage xml -i || exit 1
export OS=`uname`
if test -z "$CODECOV_TOKEN"; then
coverage xml
else
if test -n "$CODECOV_TOKEN"; then
CODECOV_JOB_NAME=`echo ${JOB_NAME} | sed -r 's/^(.*autotest_)?Pyomo_([^\/]+).*/\2/'`.$BUILD_NUMBER.$python
if test -z "$CODECOV_REPO_OWNER"; then
CODECOV_REPO_OWNER="pyomo"
fi
if test -z "CODECOV_SOURCE_BRANCH"; then
CODECOV_SOURCE_BRANCH="main"
fi
i=0
while /bin/true; do
i=$[$i+1]
echo "Uploading coverage to codecov (attempt $i)"
codecov -X gcovcodecov -X gcov -X s3 --no-color \
-t $CODECOV_TOKEN --root `pwd` -e OS,python \
--name $CODECOV_JOB_NAME $CODECOV_ARGS \
| tee .cover.upload
if test $? == 0 -a `grep -i error .cover.upload \
| grep -v branch= | wc -l` -eq 0; then
codecovcli -v upload-process --sha $PYOMO_SOURCE_SHA \
--fail-on-error --git-service github --token $CODECOV_TOKEN \
--slug pyomo/pyomo --file coverage.xml --disable-search \
--name $CODECOV_JOB_NAME \
--branch $CODECOV_REPO_OWNER:$CODECOV_SOURCE_BRANCH \
--env OS,python --network-root-folder `pwd` --plugin noop
if test $? == 0; then
break
elif test $i -ge 4; then
exit 1
Expand Down
28 changes: 15 additions & 13 deletions .codecov.yml → codecov.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
codecov:
notify:
# GHA: 5, Jenkins: 11
# Accurate as of July 3, 2024
# Potential to change when Python versions change
after_n_builds: 16
wait_for_ci: true
coverage:
range: "50...100"
range:
- 50.0
- 100.0
status:
patch:
default:
# Force patches to be covered at the level of the codebase
threshold: 0.0
project:
default:
# Allow overall coverage to drop to avoid failures due to code
# cleanup or CI unavailability/lag
threshold: 5%
patch:
default:
# Force patches to be covered at the level of the codebase
threshold: 0%
# ci:
# - !ci.appveyor.com
codecov:
notify:
# GHA: 4, Jenkins: 8
after_n_builds: 12 # all
wait_for_ci: yes
threshold: 5.0
2 changes: 1 addition & 1 deletion pyomo/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ class will still create ``c`` instances that only have the single
:py:meth:`generate_documentation()`. The simplest is
:py:meth:`display()`, which prints out the current values of the
configuration object (and if it is a container type, all of it's
children). :py:meth:`generate_yaml_template` is simular to
children). :py:meth:`generate_yaml_template` is similar to
:py:meth:`display`, but also includes the description fields as
formatted comments.
Expand Down
10 changes: 8 additions & 2 deletions pyomo/common/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,10 +999,13 @@ def _finalize_numpy(np, available):
# registration here (to bypass the deprecation warning) until we
# finally remove all support for it
numeric_types._native_boolean_types.add(t)
_floats = [np.float_, np.float16, np.float32, np.float64]
_floats = [np.float16, np.float32, np.float64]
# float96 and float128 may or may not be defined in this particular
# numpy build (it depends on platform and version).
# Register them only if they are present
if hasattr(np, 'float_'):
# Prepend to preserve previous functionality
_floats.insert(0, np.float_)
if hasattr(np, 'float96'):
_floats.append(np.float96)
if hasattr(np, 'float128'):
Expand All @@ -1013,10 +1016,13 @@ def _finalize_numpy(np, available):
# registration here (to bypass the deprecation warning) until we
# finally remove all support for it
numeric_types._native_boolean_types.add(t)
_complex = [np.complex_, np.complex64, np.complex128]
_complex = [np.complex64, np.complex128]
# complex192 and complex256 may or may not be defined in this
# particular numpy build (it depends on platform and version).
# Register them only if they are present
if hasattr(np, 'np.complex_'):
# Prepend to preserve functionality
_complex.insert(0, np.complex_)
if hasattr(np, 'complex192'):
_complex.append(np.complex192)
if hasattr(np, 'complex256'):
Expand Down
2 changes: 1 addition & 1 deletion pyomo/common/tests/test_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def test_and_or(self):
_and_or = avail0 & avail1 | avail2
self.assertTrue(_and_or)

# Verify operator prescedence
# Verify operator precedence
_or_and = avail0 | avail2 & avail2
self.assertTrue(_or_and)
_or_and = (avail0 | avail2) & avail2
Expand Down
35 changes: 28 additions & 7 deletions pyomo/common/unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ def filter_fcn(self, line):
return False

def filter_file_contents(self, lines, abstol=None):
_numpy_scalar_re = re.compile(r'np.(int|float)\d+\(([^\)]+)\)')
filtered = []
deprecated = None
for line in lines:
Expand All @@ -807,29 +808,49 @@ def filter_file_contents(self, lines, abstol=None):
item_list = []
items = line.strip().split()
for i in items:
# Split up lists, dicts, and sets
while i and i[0] in '[{':
item_list.append(i[0])
i = i[1:]
tail = []
while i and i[-1] in ',:]}':
tail.append(i[-1])
i = i[:-1]

# A few substitutions to get tests passing on pypy3
if ".inf" in i:
i = i.replace(".inf", "inf")
if "null" in i:
i = i.replace("null", "None")

try:
item_list.append(float(i))
# Numpy 2.x changed the repr for scalars. Convert
# the new scalar reprs back to the original (which
# were indistinguishable from python floats/ints)
np_match = _numpy_scalar_re.match(i)
if np_match:
item_list.append(float(np_match.group(2)))
else:
item_list.append(float(i))
except:
item_list.append(i)
if tail:
tail.reverse()
item_list.extend(tail)

# We can get printed results objects where the baseline is
# exactly 0 (and omitted) and the test is slightly non-zero.
# We will look for the pattern of values printed from
# results objects and remote them if they are within
# tolerance of 0
if (
len(item_list) == 2
and item_list[0] == 'Value:'
and type(item_list[1]) is float
and abs(item_list[1]) < (abstol or 0)
and len(filtered[-1]) == 1
and filtered[-1][0][-1] == ':'
len(item_list) == 3
and item_list[0] == 'Value'
and item_list[1] == ':'
and type(item_list[2]) is float
and abs(item_list[2]) < (abstol or 0)
and len(filtered[-1]) == 2
and filtered[-1][1] == ':'
):
filtered.pop()
else:
Expand Down
6 changes: 3 additions & 3 deletions pyomo/core/base/set.py
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,7 @@ class InsertionOrder(object):
class SortedOrder(object):
pass

_ValidOrderedAuguments = {True, False, InsertionOrder, SortedOrder}
_ValidOrderedArguments = {True, False, InsertionOrder, SortedOrder}
_UnorderedInitializers = {set}

@overload
Expand Down Expand Up @@ -2015,7 +2015,7 @@ def __new__(cls, *args, **kwds):
ordered = kwds.get('ordered', Set.InsertionOrder)
if ordered is True:
ordered = Set.InsertionOrder
if ordered not in Set._ValidOrderedAuguments:
if ordered not in Set._ValidOrderedArguments:
if inspect.isfunction(ordered):
ordered = Set.SortedOrder
else:
Expand All @@ -2032,7 +2032,7 @@ def __new__(cls, *args, **kwds):
str(_)
for _ in sorted_robust(
'Set.' + x.__name__ if isinstance(x, type) else x
for x in Set._ValidOrderedAuguments.union(
for x in Set._ValidOrderedArguments.union(
{'<function>'}
)
)
Expand Down
10 changes: 6 additions & 4 deletions pyomo/core/kernel/register_numpy_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@
# Historically, the lists included several numpy aliases
numpy_int_names.extend(('int_', 'intc', 'intp'))
numpy_int.extend((numpy.int_, numpy.intc, numpy.intp))
numpy_float_names.append('float_')
numpy_float.append(numpy.float_)
numpy_complex_names.append('complex_')
numpy_complex.append(numpy.complex_)
if hasattr(numpy, 'float_'):
numpy_float_names.append('float_')
numpy_float.append(numpy.float_)
if hasattr(numpy, 'complex_'):
numpy_complex_names.append('complex_')
numpy_complex.append(numpy.complex_)

# Re-build the old numpy_* lists
for t in native_boolean_types:
Expand Down
2 changes: 1 addition & 1 deletion pyomo/core/plugins/transform/radix_linearization.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def _collect_bilinear(self, expr, bilin, quad):
if type(expr) is PowExpression and value(expr._args[1]) == 2:
# Note: directly testing the value of the exponent above is
# safe: we have already verified that this expression is
# polynominal, so the exponent must be constant.
# polynomial, so the exponent must be constant.
tmp = ProductExpression()
tmp._numerator = [expr._args[0], expr._args[0]]
tmp._denominator = []
Expand Down
11 changes: 8 additions & 3 deletions pyomo/core/tests/unit/test_kernel_register_numpy_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
# Boolean
numpy_bool_names = []
if numpy_available:
numpy_bool_names.append('bool_')
if numpy.__version__[0] == '2':
numpy_bool_names.append('bool')
else:
numpy_bool_names.append('bool_')
# Integers
numpy_int_names = []
if numpy_available:
Expand All @@ -34,7 +37,8 @@
# Reals
numpy_float_names = []
if numpy_available:
numpy_float_names.append('float_')
if hasattr(numpy, 'float_'):
numpy_float_names.append('float_')
numpy_float_names.append('float16')
numpy_float_names.append('float32')
numpy_float_names.append('float64')
Expand All @@ -46,7 +50,8 @@
# Complex
numpy_complex_names = []
if numpy_available:
numpy_complex_names.append('complex_')
if hasattr(numpy, 'complex_'):
numpy_complex_names.append('complex_')
numpy_complex_names.append('complex64')
numpy_complex_names.append('complex128')
if hasattr(numpy, 'complex192'):
Expand Down
8 changes: 4 additions & 4 deletions pyomo/core/tests/unit/test_numvalue.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,10 +552,10 @@ def test_unknownNumericType(self):

@unittest.skipUnless(numpy_available, "This test requires NumPy")
def test_numpy_basic_float_registration(self):
self.assertIn(numpy.float_, native_numeric_types)
self.assertNotIn(numpy.float_, native_integer_types)
self.assertIn(numpy.float_, _native_boolean_types)
self.assertIn(numpy.float_, native_types)
self.assertIn(numpy.float64, native_numeric_types)
self.assertNotIn(numpy.float64, native_integer_types)
self.assertIn(numpy.float64, _native_boolean_types)
self.assertIn(numpy.float64, native_types)

@unittest.skipUnless(numpy_available, "This test requires NumPy")
def test_numpy_basic_int_registration(self):
Expand Down
12 changes: 6 additions & 6 deletions pyomo/core/tests/unit/test_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ def setUp(self):
self.instance = self.model.create_instance(currdir + "setA.dat")
self.e1 = numpy.bool_(1)
self.e2 = numpy.int_(2)
self.e3 = numpy.float_(3.0)
self.e3 = numpy.float64(3.0)
self.e4 = numpy.int_(4)
self.e5 = numpy.int_(5)
self.e6 = numpy.int_(6)
Expand All @@ -1068,7 +1068,7 @@ def test_numpy_int(self):

def test_numpy_float(self):
model = ConcreteModel()
model.A = Set(initialize=[numpy.float_(1.0), numpy.float_(0.0)])
model.A = Set(initialize=[numpy.float64(1.0), numpy.float64(0.0)])
self.assertEqual(model.A.bounds(), (0, 1))


Expand Down Expand Up @@ -3213,7 +3213,7 @@ def test_numpy_membership(self):
self.assertEqual(numpy.int_(1) in Boolean, True)
self.assertEqual(numpy.bool_(True) in Boolean, True)
self.assertEqual(numpy.bool_(False) in Boolean, True)
self.assertEqual(numpy.float_(1.1) in Boolean, False)
self.assertEqual(numpy.float64(1.1) in Boolean, False)
self.assertEqual(numpy.int_(2) in Boolean, False)

self.assertEqual(numpy.int_(0) in Integers, True)
Expand All @@ -3222,7 +3222,7 @@ def test_numpy_membership(self):
# identically to 1
self.assertEqual(numpy.bool_(True) in Integers, True)
self.assertEqual(numpy.bool_(False) in Integers, True)
self.assertEqual(numpy.float_(1.1) in Integers, False)
self.assertEqual(numpy.float64(1.1) in Integers, False)
self.assertEqual(numpy.int_(2) in Integers, True)

self.assertEqual(numpy.int_(0) in Reals, True)
Expand All @@ -3231,14 +3231,14 @@ def test_numpy_membership(self):
# identically to 1
self.assertEqual(numpy.bool_(True) in Reals, True)
self.assertEqual(numpy.bool_(False) in Reals, True)
self.assertEqual(numpy.float_(1.1) in Reals, True)
self.assertEqual(numpy.float64(1.1) in Reals, True)
self.assertEqual(numpy.int_(2) in Reals, True)

self.assertEqual(numpy.int_(0) in Any, True)
self.assertEqual(numpy.int_(1) in Any, True)
self.assertEqual(numpy.bool_(True) in Any, True)
self.assertEqual(numpy.bool_(False) in Any, True)
self.assertEqual(numpy.float_(1.1) in Any, True)
self.assertEqual(numpy.float64(1.1) in Any, True)
self.assertEqual(numpy.int_(2) in Any, True)

def test_setargs1(self):
Expand Down
Loading

0 comments on commit 072c2c5

Please sign in to comment.