Repository: bird-house/birdy

Issue:
function signature is confused by default and min_occurs mismatch
## Description

Not sure if this is a bug, but when a process has inputs with min_occurs=1 followed by processes with min_occurs but with a default value (which is strange but allowed), the python signature assigns wrong defaults to these arguments. This can be fixed by making sure that inputs with default arguments have min_occurs=0.



Comments:

Patch:
diff --git a/birdy/client/base.py b/birdy/client/base.py
index 71f8eec..1fd5855 100644
--- a/birdy/client/base.py
+++ b/birdy/client/base.py
@@ -165,20 +165,6 @@ class WPSClient(object):
 
         process = self._processes[pid]
 
-        def sort_inputs_key(i):
-            """Function used as key when sorting process inputs.
-
-            The order is:
-             - Inputs that have minOccurs >= 1 and no default value
-             - Inputs that have minOccurs >= 1 and a default value
-             - Every other input
-            """
-            return list(reversed([
-                i.minOccurs >= 1 and i.defaultValue is None,
-                i.minOccurs >= 1,
-                i.minOccurs == 0,
-            ]))
-
         required_inputs_first = sorted(process.dataInputs, key=sort_inputs_key)
 
         input_names = []
@@ -325,6 +311,27 @@ class WPSClient(object):
             self.logger.info("{} failed.".format(execution.process.identifier))
 
 
+def sort_inputs_key(i):
+    """Function used as key when sorting process inputs.
+
+    The order is:
+     - Inputs that have minOccurs >= 1 and no default value
+     - Inputs that have minOccurs >= 1 and a default value
+     - Every other input
+
+    Parameters
+    ----------
+    i: owslib.wps.Input
+      An owslib Input
+    """
+    conditions = [
+        i.minOccurs >= 1 and i.defaultValue is None,
+        i.minOccurs >= 1,
+        i.minOccurs == 0,
+    ]
+    return [not c for c in conditions]  # False values are sorted first
+
+
 def nb_form(wps, pid):
     """Return a Notebook form to enter input values and launch process."""
     if wps._notebook:


Test patch:
diff --git a/tests/test_client.py b/tests/test_client.py
index f9881d0..97bb7bc 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -1,15 +1,17 @@
 import datetime
 import os
-import pytest
 import json
+import tempfile
+from pathlib import Path
+from unittest import mock
+
+import pytest
 # from owslib import crs
 
-from pathlib import Path
 from birdy.client import converters, nb_form
+from birdy.client.base import sort_inputs_key
 from birdy.client.utils import is_embedded_in_request
 from birdy import WPSClient
-from io import StringIO, BytesIO
-import tempfile
 
 
 # These tests assume Emu is running on the localhost
@@ -253,6 +255,34 @@ def test_xarray_converter(wps):
     assert isinstance(ncdata, xr.Dataset)
 
 
+def test_sort_inputs():
+    """
+    The order should be:
+     - Inputs that have minOccurs >= 1 and no default value
+     - Inputs that have minOccurs >= 1 and a default value
+     - Every other input
+    """
+
+    i = mock.Mock()
+    i.minOccurs = 1
+    i.defaultValue = None
+    assert sort_inputs_key(i) == [False, False, True]
+
+    i = mock.Mock()
+    i.minOccurs = 1
+    i.defaultValue = "default"
+    assert sort_inputs_key(i) == [True, False, True]
+
+    i = mock.Mock()
+    i.minOccurs = 0
+    assert sort_inputs_key(i) == [True, True, False]
+
+    i = mock.Mock()
+    i.minOccurs = 0
+    i.defaultValue = "default"
+    assert sort_inputs_key(i) == [True, True, False]
+
+
 def test_all_subclasses():
     c = converters.all_subclasses(converters.BaseConverter)
     assert converters.Meta4Converter in c