Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/datasource/data_connector/util.py b/great_expectations/datasource/data_connector/util.py
--- a/great_expectations/datasource/data_connector/util.py
+++ b/great_expectations/datasource/data_connector/util.py
@@ -137,20 +137,43 @@ def convert_data_reference_string_to_batch_identifiers_using_regex(
     group_names: List[str],
 ) -> Optional[Tuple[str, IDDict]]:
     # noinspection PyUnresolvedReferences
-    matches: Optional[re.Match] = re.match(regex_pattern, data_reference)
+    pattern = re.compile(regex_pattern)
+    matches: Optional[re.Match] = pattern.match(data_reference)
     if matches is None:
         return None
-    groups: list = list(matches.groups())
-    batch_identifiers: IDDict = IDDict(dict(zip(group_names, groups)))
+
+    # Check for `(?P<name>)` named group syntax
+    match_dict = matches.groupdict()
+    if match_dict:  # Only named groups will populate this dict
+        batch_identifiers = _determine_batch_identifiers_using_named_groups(
+            match_dict, group_names
+        )
+    else:
+        groups: list = list(matches.groups())
+        batch_identifiers: IDDict = IDDict(dict(zip(group_names, groups)))
 
     # TODO: <Alex>Accommodating "data_asset_name" inside batch_identifiers (e.g., via "group_names") is problematic; we need a better mechanism.</Alex>
     # TODO: <Alex>Update: Approach -- we can differentiate "def map_data_reference_string_to_batch_definition_list_using_regex(()" methods between ConfiguredAssetFilesystemDataConnector and InferredAssetFilesystemDataConnector so that IDDict never needs to include data_asset_name. (ref: https://superconductivedata.slack.com/archives/C01C0BVPL5Q/p1603843413329400?thread_ts=1603842470.326800&cid=C01C0BVPL5Q)</Alex>
-    data_asset_name: str = DEFAULT_DATA_ASSET_NAME
-    if "data_asset_name" in batch_identifiers:
-        data_asset_name = batch_identifiers.pop("data_asset_name")
+    data_asset_name: str = batch_identifiers.pop(
+        "data_asset_name", DEFAULT_DATA_ASSET_NAME
+    )
     return data_asset_name, batch_identifiers
 
 
+def _determine_batch_identifiers_using_named_groups(
+    match_dict: dict, group_names: List[str]
+) -> IDDict:
+    batch_identifiers = IDDict()
+    for key, value in match_dict.items():
+        if key in group_names:
+            batch_identifiers[key] = value
+        else:
+            logger.warn(
+                f"The named group '{key}' must explicitly be stated in group_names to be parsed"
+            )
+    return batch_identifiers
+
+
 def map_batch_definition_to_data_reference_string_using_regex(
     batch_definition: BatchDefinition,
     regex_pattern: str,


Test patch:
diff --git a/tests/datasource/data_connector/test_data_connector_util.py b/tests/datasource/data_connector/test_data_connector_util.py
--- a/tests/datasource/data_connector/test_data_connector_util.py
+++ b/tests/datasource/data_connector/test_data_connector_util.py
@@ -231,6 +231,41 @@ def test_convert_data_reference_string_to_batch_identifiers_using_regex():
     )
 
 
+def test_convert_data_reference_string_to_batch_identifiers_using_regex_with_named_groups(
+    caplog,
+):
+    data_reference = "alex_20200809_1000.csv"
+    pattern = r"^(?P<name>.+)_(?P<timestamp>\d+)_(?P<price>\d+)\.csv$"
+
+    group_names = ["name", "timestamp", "price"]
+    assert convert_data_reference_string_to_batch_identifiers_using_regex(
+        data_reference=data_reference, regex_pattern=pattern, group_names=group_names
+    ) == (
+        "DEFAULT_ASSET_NAME",
+        IDDict(
+            {
+                "name": "alex",
+                "timestamp": "20200809",
+                "price": "1000",
+            }
+        ),
+    )
+
+    group_names = ["name", "timestamp", "cost"]  # Mismatch between "price" and "cost"!
+    assert convert_data_reference_string_to_batch_identifiers_using_regex(
+        data_reference=data_reference, regex_pattern=pattern, group_names=group_names
+    ) == (
+        "DEFAULT_ASSET_NAME",
+        IDDict(
+            {
+                "name": "alex",
+                "timestamp": "20200809",
+            }
+        ),
+    )
+    assert "The named group 'price' must explicitly be stated" in caplog.text
+
+
 def test_map_batch_definition_to_data_reference_string_using_regex():
     # not BatchDefinition
     my_batch_definition = "I_am_a_string"