From b6f0097a3190a05571a86e28ab1dbf7c626cbf00 Mon Sep 17 00:00:00 2001 From: William Hart Date: Wed, 24 Jan 2018 22:12:03 -0700 Subject: [PATCH 1/9] Removing testing and support for Python 2.6 This commit does not include changes in the Pyomo source tree that are not backwards compatible, but I expect that subsequent commits will begin to introduce changes that are not compatible with Python 2.6. --- .appveyor.yml | 6 ++---- .travis.yml | 16 ++++------------ .travis_install_gams_api.sh | 5 ----- CHANGELOG.txt | 6 ++++++ admin/jenkins.py | 6 +----- scripts/pyomo_install | 4 ++-- setup.py | 1 - 7 files changed, 15 insertions(+), 29 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index cd98e0c93e8..58c15a7f248 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,7 @@ environment: # For Python versions available on Appveyor, see # http://www.appveyor.com/docs/installed-software#python - # The list here is complete (excluding Python 2.6, which - # isn't covered by this document) at the time of writing. + # The list here is complete at the time of writing. - PYTHON_VERSION: 2.7 #PYTHON: "C:\\Python27" @@ -74,7 +73,6 @@ install: - conda config --set auto_update_conda false # - "%CONDAFORGE% setuptools pip" - - "IF %PYTHON_VERSION%==2.6 (python -m pip install ordereddict)" - python -m pip install coverage - python -m pip install codecov - IF DEFINED YAML (python -m pip install pyyaml) @@ -83,7 +81,7 @@ install: - python -m pip install openpyxl - python -m pip install sphinx_rtd_theme - "%ANACONDA% pandas networkx" - - "IF NOT %PYTHON_VERSION%==2.6 (%ANACONDA% scipy)" + - "%ANACONDA% scipy" # # Install GAMS # diff --git a/.travis.yml b/.travis.yml index 241a651cc49..b3148fb648b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,6 @@ language: python matrix: include: - # NOTE: EXTRAS is not yet supported on Python 2.6. - - python: '2.6' - env: CATEGORY="nightly" - python: '2.7' env: CATEGORY="nightly" - python: '3.6' @@ -69,11 +66,6 @@ install: - which pip - pip --version # - - if [ "${TRAVIS_PYTHON_VERSION}" == "2.6" ]; then pip install 'cryptography<2.1.1'; fi - - if [ "${TRAVIS_PYTHON_VERSION}" == "2.6" ]; then pip install 'pyOpenSSL<17.5'; fi - - if [ "${TRAVIS_PYTHON_VERSION}" == "2.6" ]; then pip install urllib3; fi - - if [ "${TRAVIS_PYTHON_VERSION}" == "2.6" ]; then pip install ordereddict; fi - # - pip install coverage - pip install codecov - if [ -n "${YAML}" ]; then @@ -88,7 +80,7 @@ install: - pip install dill - conda install -q -y -c anaconda pandas networkx - - if [ "${TRAVIS_PYTHON_VERSION}" != "2.6" -a -n "${EXTRAS}" ]; then + - if [ -n "${EXTRAS}" ]; then conda install -q -y -c anaconda scipy; fi @@ -98,9 +90,9 @@ install: - wget https://d37drm4t2jghv5.cloudfront.net/distributions/24.8.5/linux/linux_x64_64_sfx.exe - chmod u+x linux_x64_64_sfx.exe - ./linux_x64_64_sfx.exe > /dev/null - # Only install GAMS API if EXTRAS is not being installed and Python is - # not 2.6, since those tests segfault on travis for an unknown reason. - - if [ "${TRAVIS_PYTHON_VERSION}" != "2.6" -a -z "${EXTRAS}" ]; then + # Only install GAMS API if EXTRAS is not being installed, + # since those tests segfault on travis for an unknown reason. + - if [ -a -z "${EXTRAS}" ]; then bash ./.travis_install_gams_api.sh; fi - export PATH=${PATH}:$PWD/gams24.8_linux_x64_64_sfx; diff --git a/.travis_install_gams_api.sh b/.travis_install_gams_api.sh index 463243d0feb..c2a752eadde 100644 --- a/.travis_install_gams_api.sh +++ b/.travis_install_gams_api.sh @@ -2,11 +2,6 @@ # Install GAMS-Python API bindings # No explicit API version for python 3.5, use 3.4 # -if [ "${TRAVIS_PYTHON_VERSION}" = "2.6" ]; then - pushd $PWD/gams24.8_linux_x64_64_sfx/apifiles/Python/api_26; - python setup.py install; - popd; -fi if [ "${TRAVIS_PYTHON_VERSION}" = "2.7" ]; then pushd $PWD/gams24.8_linux_x64_64_sfx/apifiles/Python/api; python setup.py install; diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d9914caaad2..f3632e68db8 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,12 @@ Pyomo CHANGELOG =============== +------------------------------------------------------------------------------- +Pyomo 5.4 +------------------------------------------------------------------------------- + +- Removing testing for Python 2.6 + ------------------------------------------------------------------------------- Pyomo 5.3 ------------------------------------------------------------------------------- diff --git a/admin/jenkins.py b/admin/jenkins.py index 045d1c736fe..ee9d6821889 100644 --- a/admin/jenkins.py +++ b/admin/jenkins.py @@ -12,11 +12,7 @@ import sys import os import subprocess -try: - from subprocess import check_output as _run_cmd -except: - # python 2.6 - from subprocess import check_call as _run_cmd +from subprocess import check_output as _run_cmd import driver config = sys.argv[1] diff --git a/scripts/pyomo_install b/scripts/pyomo_install index 0e6f8ac38b4..2b6a590c146 100755 --- a/scripts/pyomo_install +++ b/scripts/pyomo_install @@ -22,9 +22,9 @@ except ImportError: from urllib import pathname2url as pathname2url -if sys.version_info < (2, 6): +if sys.version_info < (2, 7): print('ERROR: %s' % sys.exc_info()[1]) - print('ERROR: This script requires Python 2.6 or greater.') + print('ERROR: This script requires Python 2.7 or greater.') sys.exit(1) # diff --git a/setup.py b/setup.py index e56c8340103..97cf100e408 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,6 @@ def read(*rnames): 'Operating System :: Unix', 'Programming Language :: Python', 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', From 404e3163dd102ef62cccce0b1511c65311501a65 Mon Sep 17 00:00:00 2001 From: William Hart Date: Sun, 15 Apr 2018 14:53:17 -0600 Subject: [PATCH 2/9] Added python_requires to setup.py This allows Python 2.7.x and versions greater than 3.5.x --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 0009a98a2c8..8ce7b98d6c9 100644 --- a/setup.py +++ b/setup.py @@ -94,6 +94,7 @@ def read(*rnames): packages=packages, keywords=['optimization'], install_requires=requires, + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*' entry_points=""" [console_scripts] runbenders=pyomo.pysp.benders:Benders_main From a3fb5017c40ea2a984116b590c86919e7ce9a00f Mon Sep 17 00:00:00 2001 From: William Hart Date: Sun, 15 Apr 2018 15:17:05 -0600 Subject: [PATCH 3/9] Removing tag for Python 3.4 We are no longer testing 3.4, so we should not advertise support for 3.4 --- admin/performance/simple.py | 59 +++++++++++++++++++++++++++++++------ setup.py | 1 - 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/admin/performance/simple.py b/admin/performance/simple.py index d9f82966a29..982d4bb463d 100644 --- a/admin/performance/simple.py +++ b/admin/performance/simple.py @@ -1,15 +1,18 @@ from pyomo.environ import * -import pyomo.core.kernel.expr as EXPR import timeit import signal coopr3 = True -pyomo4 = True +pyomo4 = False if coopr3 or pyomo4: from pyomo.repn import generate_ampl_repn + import pyomo.core.kernel.expr as EXPR + def Sum(*args, linear=None): + return sum(*args) else: from pyomo.repn import generate_standard_repn + import pyomo.core.expr.current as EXPR class TimeoutError(Exception): pass @@ -36,9 +39,21 @@ def __exit__(self, type, value, traceback): def linear(flag): - if flag == 1: + if flag == 0: + expr=sum(model.x[i] for i in model.A) + elif flag == 10: + with EXPR.linear_expression as expr: + expr=sum((model.x[i] for i in model.A), expr) + elif flag == 20: + expr=Sum(model.x[i] for i in model.A) + + elif flag == 1: expr = summation(model.p, model.x) elif flag == 6: + expr=Sum((model.p[i]*model.x[i] for i in model.A), linear=False) + elif flag == 16: + expr=Sum((model.p[i]*model.x[i] for i in model.A), linear=True) + elif flag == 26: expr=Sum(model.p[i]*model.x[i] for i in model.A) elif flag == 2: @@ -67,6 +82,9 @@ def linear(flag): elif flag == 12: with EXPR.linear_expression as expr: expr=sum((model.p[i]*model.x[i] for i in model.A), expr) + elif flag == 22: + with EXPR.nonlinear_expression as expr: + expr=sum((model.p[i]*model.x[i] for i in model.A), expr) elif flag == 13: with EXPR.linear_expression as expr: for i in model.A: @@ -84,11 +102,31 @@ def linear(flag): expr=0 for i in model.A: expr += model.p[i] * (1 + model.x[i]) - elif flag == 17: with EXPR.linear_expression as expr: for i in model.A: expr += model.p[i] * (1 + model.x[i]) + elif flag == 27: + expr = Sum(model.p[i]*(1 + model.x[i]) for i in model.A) + + elif flag == 8: + expr=0 + for i in model.A: + expr += (model.x[i]+model.x[i]) + elif flag == 18: + # This will assume a nonlinear sum + expr = Sum((model.x[i] + model.x[i]) for i in model.A) + + elif flag == 9: + expr=0 + for i in model.A: + expr += model.p[i]*(model.x[i]+model.x[i]) + elif flag == 19: + # This will assume a nonlinear sum + expr = Sum(model.p[i]*(model.x[i] + model.x[i]) for i in model.A) + + elif flag == -9: + expr = Sum(sin(model.x[i]) for i in model.A) if coopr3 or pyomo4: generate_ampl_repn(expr) @@ -98,19 +136,22 @@ def linear(flag): if coopr3: import pyomo.core.kernel.expr_coopr3 as COOPR3 print("REFCOUNT: "+str(COOPR3._getrefcount_available)) - for i in (2,3,7): + for i in (0,2,3,6,7,8,9): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) if pyomo4: import pyomo.core.kernel.expr_pyomo4 as PYOMO4 EXPR.set_expression_tree_format(EXPR.common.Mode.pyomo4_trees) print("REFCOUNT: "+str(PYOMO4._getrefcount_available)) - for i in (2,3,7): + for i in (0,2,3,6,7,8,9): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) if not (coopr3 or pyomo4): - import pyomo.core.kernel.expr_pyomo5 as PYOMO5 - print("REFCOUNT: "+str(PYOMO5._getrefcount_available)) - for i in (2,12,3,13,4,14,5,15,7,17): + import pyomo.core.expr.expr_pyomo5 as PYOMO5 + #print("REFCOUNT: "+str(PYOMO5._getrefcount_available)) + #import cProfile + #cProfile.run("linear(7)", "stats.7") + for i in (0,10,20,2,12,22,3,13,4,14,5,15,6,16,26,7,17,27,8,18,9,19,-9): + #for i in (6,16,26): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) diff --git a/setup.py b/setup.py index 8ce7b98d6c9..ab010132480 100644 --- a/setup.py +++ b/setup.py @@ -83,7 +83,6 @@ def read(*rnames): 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: CPython', From 25891881573d7418bd3268735304071576c42482 Mon Sep 17 00:00:00 2001 From: William Hart Date: Sun, 15 Apr 2018 16:48:41 -0600 Subject: [PATCH 4/9] Adding installation documentation As discussed in the PR, we to include installation instructions in our documentation, including a summary of supported versions. --- doc/OnlineDocs/getting_started/index.rst | 57 ++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/doc/OnlineDocs/getting_started/index.rst b/doc/OnlineDocs/getting_started/index.rst index 4d9b26e1845..efbde785fff 100644 --- a/doc/OnlineDocs/getting_started/index.rst +++ b/doc/OnlineDocs/getting_started/index.rst @@ -1,9 +1,58 @@ Getting Started =============== -Installation, pyomo command, a simple example, etc +Installation +------------ -.. doctest:: +Pyomo currently supports the following versions of Python: + +* CPython: 2.7, 3.5, 3.6 + + +Using CONDA +~~~~~~~~~~~ + +We recommend installation with *conda*, which is included with the Anaconda +distribution of Python. If you have a different Python distribution, then +you can install *miniconda* using *pip*: + +.. bash:: + pip install miniconda + +You can install Pyomo in your system Python installation +by executing the following in a shell: + +.. bash:: + conda install -c conda-forge pyomo + +Pyomo also has conditional dependencies on a variety of third-party Python packages. These can also be installed with conda: + +.. bash:: + conda install -c conda-forge pyomo.extras + +Optimization solvers are not installed with Pyomo, but some open source optimization solvers can be installed with conda as well: + +.. bash:: + conda install -c conda-forge pyomo.solvers + + +Using PIP +~~~~~~~~~ + +The standard utility for installing Python packages is *pip*. You +can install Pyomo in your system Python installation by executing +the following in a shell: + +.. bash:: + pip install pyomo + +However, *pip* does not support the robust installation of conditional +dependencies (i.e. the third-party Python packages or the solvers +that Pyomo may use). + + +A Simple Example +---------------- + +TODO pyomo command, importing pyomo, using NEOS, etc - >>> print('Hello World') - Hello World From fbc9ee19f513e0c8a12b285536e388692c6fc2b0 Mon Sep 17 00:00:00 2001 From: William Hart Date: Sun, 15 Apr 2018 23:47:23 -0600 Subject: [PATCH 5/9] Bug fix --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ab010132480..a8997018a47 100644 --- a/setup.py +++ b/setup.py @@ -93,7 +93,7 @@ def read(*rnames): packages=packages, keywords=['optimization'], install_requires=requires, - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*' + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', entry_points=""" [console_scripts] runbenders=pyomo.pysp.benders:Benders_main From f256f254d6f9be66e6357fbe2a441ca37d4619d2 Mon Sep 17 00:00:00 2001 From: William Hart Date: Mon, 16 Apr 2018 17:29:33 -0600 Subject: [PATCH 6/9] Re-adding support for Python 3.4 --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a8997018a47..4eaf47d8f8a 100644 --- a/setup.py +++ b/setup.py @@ -83,6 +83,7 @@ def read(*rnames): 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: CPython', @@ -93,7 +94,7 @@ def read(*rnames): packages=packages, keywords=['optimization'], install_requires=requires, - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', entry_points=""" [console_scripts] runbenders=pyomo.pysp.benders:Benders_main From 490aaf1fcf2bce013c430c1af2b663bdf8ff957d Mon Sep 17 00:00:00 2001 From: William Hart Date: Sat, 21 Apr 2018 22:42:14 -0600 Subject: [PATCH 7/9] Reverting a change --- admin/performance/simple.py | 59 ++++++------------------------------- 1 file changed, 9 insertions(+), 50 deletions(-) diff --git a/admin/performance/simple.py b/admin/performance/simple.py index 982d4bb463d..d9f82966a29 100644 --- a/admin/performance/simple.py +++ b/admin/performance/simple.py @@ -1,18 +1,15 @@ from pyomo.environ import * +import pyomo.core.kernel.expr as EXPR import timeit import signal coopr3 = True -pyomo4 = False +pyomo4 = True if coopr3 or pyomo4: from pyomo.repn import generate_ampl_repn - import pyomo.core.kernel.expr as EXPR - def Sum(*args, linear=None): - return sum(*args) else: from pyomo.repn import generate_standard_repn - import pyomo.core.expr.current as EXPR class TimeoutError(Exception): pass @@ -39,21 +36,9 @@ def __exit__(self, type, value, traceback): def linear(flag): - if flag == 0: - expr=sum(model.x[i] for i in model.A) - elif flag == 10: - with EXPR.linear_expression as expr: - expr=sum((model.x[i] for i in model.A), expr) - elif flag == 20: - expr=Sum(model.x[i] for i in model.A) - - elif flag == 1: + if flag == 1: expr = summation(model.p, model.x) elif flag == 6: - expr=Sum((model.p[i]*model.x[i] for i in model.A), linear=False) - elif flag == 16: - expr=Sum((model.p[i]*model.x[i] for i in model.A), linear=True) - elif flag == 26: expr=Sum(model.p[i]*model.x[i] for i in model.A) elif flag == 2: @@ -82,9 +67,6 @@ def linear(flag): elif flag == 12: with EXPR.linear_expression as expr: expr=sum((model.p[i]*model.x[i] for i in model.A), expr) - elif flag == 22: - with EXPR.nonlinear_expression as expr: - expr=sum((model.p[i]*model.x[i] for i in model.A), expr) elif flag == 13: with EXPR.linear_expression as expr: for i in model.A: @@ -102,31 +84,11 @@ def linear(flag): expr=0 for i in model.A: expr += model.p[i] * (1 + model.x[i]) + elif flag == 17: with EXPR.linear_expression as expr: for i in model.A: expr += model.p[i] * (1 + model.x[i]) - elif flag == 27: - expr = Sum(model.p[i]*(1 + model.x[i]) for i in model.A) - - elif flag == 8: - expr=0 - for i in model.A: - expr += (model.x[i]+model.x[i]) - elif flag == 18: - # This will assume a nonlinear sum - expr = Sum((model.x[i] + model.x[i]) for i in model.A) - - elif flag == 9: - expr=0 - for i in model.A: - expr += model.p[i]*(model.x[i]+model.x[i]) - elif flag == 19: - # This will assume a nonlinear sum - expr = Sum(model.p[i]*(model.x[i] + model.x[i]) for i in model.A) - - elif flag == -9: - expr = Sum(sin(model.x[i]) for i in model.A) if coopr3 or pyomo4: generate_ampl_repn(expr) @@ -136,22 +98,19 @@ def linear(flag): if coopr3: import pyomo.core.kernel.expr_coopr3 as COOPR3 print("REFCOUNT: "+str(COOPR3._getrefcount_available)) - for i in (0,2,3,6,7,8,9): + for i in (2,3,7): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) if pyomo4: import pyomo.core.kernel.expr_pyomo4 as PYOMO4 EXPR.set_expression_tree_format(EXPR.common.Mode.pyomo4_trees) print("REFCOUNT: "+str(PYOMO4._getrefcount_available)) - for i in (0,2,3,6,7,8,9): + for i in (2,3,7): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) if not (coopr3 or pyomo4): - import pyomo.core.expr.expr_pyomo5 as PYOMO5 - #print("REFCOUNT: "+str(PYOMO5._getrefcount_available)) - #import cProfile - #cProfile.run("linear(7)", "stats.7") - for i in (0,10,20,2,12,22,3,13,4,14,5,15,6,16,26,7,17,27,8,18,9,19,-9): - #for i in (6,16,26): + import pyomo.core.kernel.expr_pyomo5 as PYOMO5 + print("REFCOUNT: "+str(PYOMO5._getrefcount_available)) + for i in (2,12,3,13,4,14,5,15,7,17): print((i,timeit.timeit('linear(%d)' % i, "from __main__ import linear", number=1))) From 9116621e662f05026fe87b3d5fc07c236aa75bdf Mon Sep 17 00:00:00 2001 From: William Hart Date: Tue, 24 Apr 2018 16:25:43 -0600 Subject: [PATCH 8/9] Misc update to documentation --- CHANGELOG.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4e2595ab8d9..9549f2c095e 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,7 +6,7 @@ Pyomo CHANGELOG Current Development ------------------------------------------------------------------------------- -- Resolved Python 3.4 build errors on Appveyor. +- Resolved Python 3.4 build errors on Appveyor. (#438) - Wrap Vars in value() for assignment to numpy vectors (#436) - Adding TerminationCondition and SolverStatus to pyomo.environ (#429) - Removing testing for Python 2.6 (#322) From 5d883a2b63135da0eadbbc3f623fe52d0fa86366 Mon Sep 17 00:00:00 2001 From: William Hart Date: Tue, 24 Apr 2018 17:45:39 -0600 Subject: [PATCH 9/9] Fixes based on reviewer feedback. --- doc/OnlineDocs/getting_started/index.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/doc/OnlineDocs/getting_started/index.rst b/doc/OnlineDocs/getting_started/index.rst index efbde785fff..36ed3b5b340 100644 --- a/doc/OnlineDocs/getting_started/index.rst +++ b/doc/OnlineDocs/getting_started/index.rst @@ -6,7 +6,7 @@ Installation Pyomo currently supports the following versions of Python: -* CPython: 2.7, 3.5, 3.6 +* CPython: 2.7, 3.4, 3.5, 3.6 Using CONDA @@ -33,7 +33,7 @@ Pyomo also has conditional dependencies on a variety of third-party Python packa Optimization solvers are not installed with Pyomo, but some open source optimization solvers can be installed with conda as well: .. bash:: - conda install -c conda-forge pyomo.solvers + conda install -c conda-forge ipopt coin-cbc glpk Using PIP @@ -46,10 +46,6 @@ the following in a shell: .. bash:: pip install pyomo -However, *pip* does not support the robust installation of conditional -dependencies (i.e. the third-party Python packages or the solvers -that Pyomo may use). - A Simple Example ----------------