From a31b96eeea70788ad2e71d425f2845a52febef65 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 9 Sep 2022 12:20:12 -0600 Subject: [PATCH 1/7] update Python version to 3.8.6 --- metplus/PYTHON_VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metplus/PYTHON_VERSION b/metplus/PYTHON_VERSION index 1ac53bb4b..b91632216 100644 --- a/metplus/PYTHON_VERSION +++ b/metplus/PYTHON_VERSION @@ -1 +1 @@ -3.6.3 \ No newline at end of file +3.8.6 \ No newline at end of file From ab42acf3894a49281bee48a5bfb57f66eee730a2 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 9 Sep 2022 14:44:39 -0600 Subject: [PATCH 2/7] update python version to 3.8.6 for ReadTheDocs and the pip/conda requirements --- .readthedocs.yaml | 2 +- environment.yml | 4 ++-- requirements.txt | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index ea8b7fe79..de9f51815 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -12,7 +12,7 @@ formats: [pdf] # Optionally set the version of Python and requirements required to build your # docs python: - version: 3.7 + version: 3.8 install: - requirements: docs/requirements.txt - requirements: requirements.txt diff --git a/environment.yml b/environment.yml index 59a28da55..e660f9d5d 100644 --- a/environment.yml +++ b/environment.yml @@ -1,7 +1,7 @@ name: metplus_base channels: - - defaults + - conda-forge dependencies: - - python=3.6.3 + - python=3.8.6 - python-dateutil prefix: /home/met_test/.conda/envs/metplus_base diff --git a/requirements.txt b/requirements.txt index 58e4a9f46..9d72508e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -certifi==2020.6.20 -python-dateutil==2.8.1 -six==1.15.0 +certifi==2022.6.15 +python-dateutil==2.8.2 +six==1.16.0 From c3047a76fb96ed14afd332fc65fbc962a1e72ebc Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Fri, 9 Sep 2022 16:21:19 -0600 Subject: [PATCH 3/7] added return value checking to error and exit a non-zero value if docker build or docker push fail --- .github/jobs/docker_setup.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/jobs/docker_setup.sh b/.github/jobs/docker_setup.sh index f5c923dad..31b996c9a 100755 --- a/.github/jobs/docker_setup.sh +++ b/.github/jobs/docker_setup.sh @@ -60,6 +60,11 @@ time_command docker build --pull --cache-from ${DOCKERHUB_TAG} \ --build-arg MET_DOCKER_REPO=$MET_DOCKER_REPO \ --build-arg MET_TAG=$MET_TAG \ -f ${DOCKERFILE_PATH} ${GITHUB_WORKSPACE} +if [ $? != 0 ]; then + echo "ERROR: Docker build failed" + exit 1 +fi + # skip docker push if credentials are not set if [ -z ${DOCKER_USERNAME+x} ] || [ -z ${DOCKER_PASSWORD+x} ]; then @@ -69,6 +74,10 @@ fi echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin time_command docker push ${DOCKERHUB_TAG} +if [ $? != 0 ]; then + echo "ERROR: Docker push failed" + exit 1 +fi echo Running docker images docker images From 5418ea4cc85eef0c6712259dcc1e3fac456f6b5f Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Oct 2022 12:00:39 -0600 Subject: [PATCH 4/7] update python version to 3.8 in GitHub Actions environment --- .github/workflows/documentation.yml | 2 +- .github/workflows/testing.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index a14891b7f..9b6babefd 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: '3.6' + python-version: '3.8' - name: Install dependencies run: | python -m pip install --upgrade sphinx sphinx-gallery sphinx_rtd_theme diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index f60cb04e5..66a9d352f 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -78,7 +78,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: '3.6' + python-version: '3.8' - name: Get METplus Image run: .github/jobs/docker_setup.sh env: From ca80c9e4c391dcf2fd9f6a5b9bbd5dda703b247d Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Oct 2022 12:41:18 -0600 Subject: [PATCH 5/7] Per #1566, store the minimum version of python needed to run the wrappers in addition to the recommended version. Warn if the user's python version is less than the recommended and error if the their version is less than the minimum required --- .../util/metplus_check/test_metplus_check.py | 20 ++--- metplus/PYTHON_VERSION_MIN | 1 + metplus/__init__.py | 3 + metplus/util/metplus_check.py | 74 ++++++++++++------- 4 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 metplus/PYTHON_VERSION_MIN diff --git a/internal/tests/pytests/util/metplus_check/test_metplus_check.py b/internal/tests/pytests/util/metplus_check/test_metplus_check.py index 75377c0bb..832512dfb 100644 --- a/internal/tests/pytests/util/metplus_check/test_metplus_check.py +++ b/internal/tests/pytests/util/metplus_check/test_metplus_check.py @@ -10,19 +10,19 @@ # a later version of python passes # an earlier version of python fails @pytest.mark.parametrize( - 'user, supported, torf', [ - ('3.6.3', '3.6.3', True), # same - ('2.7', '3.6.3', False), # earlier major - ('3.6.2', '3.6.3', False), # earlier bugfix - ('3.6.4', '3.6.3', True), # later bugfix - ('3.5.5', '3.6.3', False), # earlier minor, later bugfix - ('3.8.1', '3.6.3', True), # later minor, earlier bugfix - ('4.0.0', '3.6.3', True), # later major + 'user, torf', [ + ('3.6.3', True), # same + ('2.7', False), # earlier major + ('3.6.2', False), # earlier bugfix + ('3.6.4', True), # later bugfix + ('3.5.5', False), # earlier minor, later bugfix + ('3.8.1', True), # later minor, earlier bugfix + ('4.0.0', True), # later major ] ) @pytest.mark.util -def test_metplus_check_python(user, supported, torf): - assert metplus_check.metplus_check_python_version(user, supported) == torf +def test_metplus_check_python(user, torf): + assert metplus_check.metplus_check_python_version(user) == torf # checking METPLUS_DISABLE_PLOT_WRAPPERS and METPLUS_ENABLE_PLOT_WRAPPERS diff --git a/metplus/PYTHON_VERSION_MIN b/metplus/PYTHON_VERSION_MIN new file mode 100644 index 000000000..1ac53bb4b --- /dev/null +++ b/metplus/PYTHON_VERSION_MIN @@ -0,0 +1 @@ +3.6.3 \ No newline at end of file diff --git a/metplus/__init__.py b/metplus/__init__.py index 0f09074ca..2696e90ad 100644 --- a/metplus/__init__.py +++ b/metplus/__init__.py @@ -9,6 +9,9 @@ def get_metplus_release_date(): def get_python_version(): return get_metplus_info('PYTHON_VERSION') +def get_python_version_min(): + return get_metplus_info('PYTHON_VERSION_MIN') + def get_metplus_info(info_rel_path): info_file = os.path.abspath(os.path.join(os.path.dirname(__file__), info_rel_path)) diff --git a/metplus/util/metplus_check.py b/metplus/util/metplus_check.py index b4d256b23..8a90fdc8c 100755 --- a/metplus/util/metplus_check.py +++ b/metplus/util/metplus_check.py @@ -7,38 +7,59 @@ import os import re -from .. import get_python_version +from .. import get_python_version, get_python_version_min -SUPPORTED_PY_VERSION = get_python_version() -def metplus_check_python_version(user_py, supported_py): - """!Test that the user's version of python is equal of higher than the - the supported version of python. Imported in each wrapper and run_metplus - to avoid confusing failures if the user's version is not current. Note: - SyntaxError from using f-strings (available in 3.6+) in earlier versions of - Python are output before the output from this function can be displayed. - Args: - @param user_py user's python version number, i.e. 3.8.1 - @param supported_py currently supported python version number, i.e. 3.6.3 - @returns True if version is at least supported, False if not +def metplus_check_python_version(user): + """!Test that the user's version of python is equal or higher than the + the supported version of python. Also check against the recommended + version of Python. This is used in the run_metplus.py script + to avoid confusing failures if the user's version is not current. Note: + SyntaxError from using f-strings (available in 3.6+) in earlier versions + of Python are output before the output from this function can be + displayed. + + @param user version of Python that the user is running + @returns True if version is at least supported, False if not """ - supported_list = supported_py.split('.') - user_list = user_py.split('.') + supported = get_python_version_min() + recommended = get_python_version() + + # check if user's Python version can run METplus wrappers + if not _python_version_is_sufficient(user, supported): + print("ERROR: Must be using Python {}".format(supported), + "or higher with the required packages installed." + " You are using {}.".format(user)) + print("See the METplus documentation for more information.") + return False + + # check if user's Python version is at least the recommended version + if not _python_version_is_sufficient(user, recommended): + print("WARNING: Python {}".format(recommended), + "or higher is recommended." + " You are using {}.".format(user)) + print("See the METplus documentation for more information.") + + return True - for user, supported in zip(user_list, supported_list): + +def _python_version_is_sufficient(user_version, test_version): + """! Check if user's version of Python is above or equal to another. + + @param user_version Python version of user, e.g. 3.7.3 + @param test_version Python version to compare, e.g. 3.8.6 + @returns True if user's version is sufficient, False otherwise + """ + for user, test in zip(user_version.split('.'), test_version.split('.')): # if the same version is used, continue - if int(user) == int(supported): + if int(user) == int(test): continue # if a higher version is used, break out of the loop - if int(user) > int(supported): + if int(user) > int(test): break - # a lower version is used - report and exit - print("ERROR: Must be using Python {} or higher ".format(supported_py)+ - "with the required packages installed.") - print("You are using {}.".format(user_py)) - print("See the METplus documentation for more information.") + # a lower version is used, return False return False return True @@ -54,6 +75,7 @@ def metplus_check_environment_variables(environ): return True + def evaluates_to_true(value): """!Check if the value matches an expression that should be interpretted as False Without this, environment variables that are set are interpretted as True no @@ -70,6 +92,7 @@ def evaluates_to_true(value): return True + def plot_wrappers_are_enabled(environ): """! Check METPLUS_[DISABLE/ENABLE]_PLOT_WRAPPERS. If both are set it should error and exit. Otherwise it should warn if DISABLE if used beacuse ENABLE should be @@ -97,13 +120,12 @@ def plot_wrappers_are_enabled(environ): # default behavior is to enable plot wrappers return True + # get user's python version and check that it is equal or # higher than the supported version -USER_PY_VERSION = sys.version.split(' ')[0] -compatible_python_version = metplus_check_python_version(USER_PY_VERSION, - SUPPORTED_PY_VERSION) +user_python_version = sys.version.split(' ')[0] +compatible_python_version = metplus_check_python_version(user_python_version) compatible_environment = metplus_check_environment_variables(os.environ) - if not compatible_python_version or not compatible_environment: sys.exit(1) From 4d92b2743c7ec1f0d8fbff1488c551e25519867e Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Oct 2022 12:41:52 -0600 Subject: [PATCH 6/7] import metplus_check first in metplus/util init so that f-strings do not cause a cryptic error if using Python 2 --- metplus/util/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metplus/util/__init__.py b/metplus/util/__init__.py index b4e143d39..84c242026 100644 --- a/metplus/util/__init__.py +++ b/metplus/util/__init__.py @@ -1,6 +1,6 @@ +from .metplus_check import * from .constants import * from .string_manip import * -from .metplus_check import * from .doc_util import * from .config_metplus import * from .time_util import * From 91d3accc7359f70e637abfaf9975eb730591cb50 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Thu, 27 Oct 2022 12:44:27 -0600 Subject: [PATCH 7/7] changed setup script to use the minimum version of python as the required version to install as a package --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 379a82f70..2114a77ef 100644 --- a/setup.py +++ b/setup.py @@ -8,8 +8,8 @@ with open("metplus/VERSION", "r") as fh: version = fh.read().strip() -with open("metplus/PYTHON_VERSION", "r") as fh: - python_version = fh.read().strip() +with open("metplus/PYTHON_VERSION_MIN", "r") as fh: + python_version_req = fh.read().strip() # get list of additional files needed to add to package data_files = [] @@ -18,6 +18,7 @@ ['metplus/VERSION', 'metplus/RELEASE_DATE', 'metplus/PYTHON_VERSION', + 'metplus/PYTHON_VERSION_MIN', ])) for root, _, files in os.walk('parm'): @@ -47,7 +48,7 @@ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], - python_requires=f'>={python_version}', + python_requires=f'>={python_version_req}', data_files=data_files, zip_safe=False, )