Repository: spencerahill/aospy

Issue:
Warn (or perhaps raise?) when the main script is constructed to submit zero calculations
For instance if one forgets to specify `input_vertical_datatypes` and instead uses an empty list, the main script will run and silently compute nothing.  This is confusing for users who might not be familiar with the internals in `automate.py`, which create `Calc` objects based on the product of the input options (so if one option is an empty list, zero objects will be created).

Discussion:
spencerahill: Travis failures are both kernel timeouts on our test of the tutorial notebook: https://travis-ci.org/spencerahill/aospy/jobs/356502217#L1082

These seem unrelated to this commit.

Patch:
diff --git a/.stickler.yml b/.stickler.yml
new file mode 100644
index 0000000..8745306
--- /dev/null
+++ b/.stickler.yml
@@ -0,0 +1,3 @@
+linters:
+  flake8:
+    fixer: true
diff --git a/.travis.yml b/.travis.yml
index bef0ec4..b773e28 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,8 +10,6 @@ matrix:
     env: CONDA_ENV=py27
   - python: 2.7
     env: CONDA_ENV=py27-min
-  - python: 3.4
-    env: CONDA_ENV=py34
   - python: 3.5
     env: CONDA_ENV=py35
   - python: 3.6
diff --git a/aospy/automate.py b/aospy/automate.py
index 0f3a0d7..b7a3aae 100644
--- a/aospy/automate.py
+++ b/aospy/automate.py
@@ -24,6 +24,11 @@ _VARIABLES_STR = 'variables'
 _TAG_ATTR_MODIFIERS = dict(all='', default='default_')
 
 
+class AospyException(Exception):
+    """Base exception class for the aospy package."""
+    pass
+
+
 def _get_attr_by_tag(obj, tag, attr_name):
     """Get attribute from an object via a string tag.
 
@@ -84,11 +89,6 @@ def _input_func_py2_py3():
     return input
 
 
-class AospyException(Exception):
-    """Base exception class for the aospy package."""
-    pass
-
-
 def _user_verify(input_func=_input_func_py2_py3(),
                  prompt='Perform these computations? [y/n] '):
     """Prompt the user for verification."""
@@ -487,4 +487,10 @@ def submit_mult_calcs(calc_suite_specs, exec_options=None):
         _user_verify()
     calc_suite = CalcSuite(calc_suite_specs)
     calcs = calc_suite.create_calcs()
+    if not calcs:
+        raise AospyException(
+            "The specified combination of parameters yielded zero "
+            "calculations.  Most likely, one of the parameters is "
+            "inadvertently empty."
+        )
     return _exec_calcs(calcs, **exec_options)
diff --git a/appveyor.yml b/appveyor.yml
index 71ea082..5ee68d9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,11 +10,6 @@ environment:
       PYTHON_ARCH: "32"
       CONDA_ENV: "py27"
 
-    - PYTHON: "C:\\Python34-conda64"
-      PYTHON_VERSION: "3.4"
-      PYTHON_ARCH: "64"
-      CONDA_ENV: "py34"
-
     - PYTHON: "C:\\Python35-conda64"
       PYTHON_VERSION: "3.5"
       PYTHON_ARCH: "64"
diff --git a/ci/environment-py34.yml b/ci/environment-py34.yml
deleted file mode 100644
index 66f76b0..0000000
--- a/ci/environment-py34.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: test_env
-channels:
-  - conda-forge
-dependencies:
-  - python=3.4
-  - scipy=0.18
-  - mkl=2017.0.3
-  - netCDF4
-  - xarray
-  - dask
-  - distributed
-  - pytest
-  - future
-  - matplotlib
-  - jupyter
-  - flake8
-  - pip:
-    - coveralls
-    - pytest-cov
-    - pytest-catchlog
diff --git a/ci/install_python.ps1 b/ci/install_python.ps1
index f210245..66bca52 100644
--- a/ci/install_python.ps1
+++ b/ci/install_python.ps1
@@ -8,7 +8,7 @@ $BASE_URL = "https://www.python.org/ftp/python/"
 
 function DownloadMiniconda ($python_version, $platform_suffix) {
     $webclient = New-Object System.Net.WebClient
-    $py3versions = "3.4", "3.5", "3.6"
+    $py3versions = "3.5", "3.6"
     if ($py3versions -contains $python_version) {
         $filename = "Miniconda3-latest-Windows-" + $platform_suffix + ".exe"
     } else {
diff --git a/docs/install.rst b/docs/install.rst
index 87bce46..2f70175 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -7,7 +7,7 @@ Supported platforms
 -------------------
 
 - Operating system: Windows, MacOS/Mac OS X, and Linux
-- Python: 2.7, 3.4, 3.5, and 3.6
+- Python: 2.7, 3.5, and 3.6
 
 .. note::
 
@@ -30,11 +30,6 @@ The recommended installation method is via `conda
 
   conda install -c conda-forge aospy
 
-.. note:: Python 3.4 users: `conda-forge
-          <https://conda-forge.github.io/>`_ no longer supports builds
-          of packages on Python 3.4.  Please use one of the
-          alternative installation methods described below.
-
 Alternative method #1: pip
 --------------------------
 
diff --git a/docs/whats-new.rst b/docs/whats-new.rst
index e2c4882..6ef5b18 100644
--- a/docs/whats-new.rst
+++ b/docs/whats-new.rst
@@ -11,6 +11,9 @@ v0.3 (unreleased)
 Breaking Changes
 ~~~~~~~~~~~~~~~~
 
+- Drop support for Python 3.4, since our core upstream dependency
+  xarray is also dropping it as of their 0.11 release (:pull:`255`).
+  By `Spencer Hill <https://github.com/spencerahill>`_.
 - Deprecate ``Constant`` class and ``constants.py`` module.
   Physical constants used internally by aospy are now stored
   in ``_constants.py`` (fixes :issue:`50` via :pull:`223`).
@@ -32,6 +35,11 @@ Documentation
 Enhancements
 ~~~~~~~~~~~~
 
+- Raise an exception with an informative message if
+  ``submit_mult_calcs`` (and thus the main script) generates zero
+  calculations, which can happen if one of the parameters is
+  accidentally set to an empty list (closes :issue:`253` via
+  :pull:`254`).  By `Spencer Hill <https://github.com/spencerahill>`_.
 - Suppress warnings from xarray when loading data whose dates extend
   outside the range supported by the numpy.datetime64 datatype.  aospy
   has its own logic to deal with these cases (closes :issue:`221` via
diff --git a/setup.py b/setup.py
index 529013b..b237c6e 100644
--- a/setup.py
+++ b/setup.py
@@ -51,7 +51,6 @@ setuptools.setup(
         'Operating System :: OS Independent',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Topic :: Scientific/Engineering :: Atmospheric Science'


Test patch:
diff --git a/aospy/test/test_automate.py b/aospy/test/test_automate.py
index a7ce120..52c4c96 100644
--- a/aospy/test/test_automate.py
+++ b/aospy/test/test_automate.py
@@ -268,6 +268,13 @@ def test_submit_mult_calcs(calcsuite_init_specs_single_calc, exec_options):
         calcsuite_init_specs_single_calc['output_time_regional_reductions'])
 
 
+def test_submit_mult_calcs_no_calcs(calcsuite_init_specs):
+    specs = calcsuite_init_specs.copy()
+    specs['input_vertical_datatypes'] = []
+    with pytest.raises(AospyException):
+        submit_mult_calcs(specs)
+
+
 @pytest.mark.parametrize(
     ('exec_options'),
     [dict(parallelize=True, write_to_tar=False),