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/data_context/data_context/cloud_data_context.py b/great_expectations/data_context/data_context/cloud_data_context.py
--- a/great_expectations/data_context/data_context/cloud_data_context.py
+++ b/great_expectations/data_context/data_context/cloud_data_context.py
@@ -68,6 +68,7 @@ def _init_datasource_store(self) -> None:
             "root_directory": self.root_directory,
             "ge_cloud_credentials": self.ge_cloud_config.to_dict(),
             "ge_cloud_resource_type": GeCloudRESTResource.DATASOURCE,
+            "ge_cloud_base_url": self.ge_cloud_config.base_url,
         }
 
         datasource_store: DatasourceStore = DatasourceStore(
diff --git a/great_expectations/data_context/store/ge_cloud_store_backend.py b/great_expectations/data_context/store/ge_cloud_store_backend.py
--- a/great_expectations/data_context/store/ge_cloud_store_backend.py
+++ b/great_expectations/data_context/store/ge_cloud_store_backend.py
@@ -69,10 +69,12 @@ class GeCloudStoreBackend(StoreBackend, metaclass=ABCMeta):
         }
     )
 
+    DEFAULT_BASE_URL: str = "https://app.greatexpectations.io/"
+
     def __init__(
         self,
         ge_cloud_credentials: Dict,
-        ge_cloud_base_url: str = "https://app.greatexpectations.io/",
+        ge_cloud_base_url: str = DEFAULT_BASE_URL,
         ge_cloud_resource_type: Optional[GeCloudRESTResource] = None,
         ge_cloud_resource_name: Optional[str] = None,
         suppress_store_backend_id: bool = True,


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,3 +1,4 @@
+import copy
 import datetime
 import locale
 import logging
@@ -2359,7 +2360,7 @@ def empty_cloud_data_context(
     tmp_path: pathlib.Path,
     empty_ge_cloud_data_context_config: DataContextConfig,
     ge_cloud_config: GeCloudConfig,
-) -> DataContext:
+) -> BaseDataContext:
     project_path = tmp_path / "empty_data_context"
     project_path.mkdir()
     project_path = str(project_path)
@@ -2374,6 +2375,37 @@ def empty_cloud_data_context(
     return context
 
 
+@pytest.fixture
+@mock.patch(
+    "great_expectations.data_context.store.DatasourceStore.list_keys",
+    return_value=[],
+)
+def empty_cloud_data_context_custom_base_url(
+    mock_list_keys: mock.MagicMock,  # Avoid making a call to Cloud backend during datasource instantiation
+    tmp_path: pathlib.Path,
+    empty_ge_cloud_data_context_config: DataContextConfig,
+    ge_cloud_config: GeCloudConfig,
+) -> BaseDataContext:
+    project_path = tmp_path / "empty_data_context"
+    project_path.mkdir()
+    project_path = str(project_path)
+
+    custom_base_url: str = "https://some_url.org"
+    custom_ge_cloud_config = copy.deepcopy(ge_cloud_config)
+    custom_ge_cloud_config.base_url = custom_base_url
+
+    context = ge.data_context.BaseDataContext(
+        project_config=empty_ge_cloud_data_context_config,
+        context_root_dir=project_path,
+        ge_cloud_mode=True,
+        ge_cloud_config=custom_ge_cloud_config,
+    )
+    assert context.list_datasources() == []
+    assert context.ge_cloud_config.base_url != ge_cloud_config.base_url
+    assert context.ge_cloud_config.base_url == custom_base_url
+    return context
+
+
 @pytest.fixture
 def cloud_data_context_with_datasource_pandas_engine(empty_cloud_data_context):
     context = empty_cloud_data_context
diff --git a/tests/data_context/test_data_context_ge_cloud_mode.py b/tests/data_context/test_data_context_ge_cloud_mode.py
--- a/tests/data_context/test_data_context_ge_cloud_mode.py
+++ b/tests/data_context/test_data_context_ge_cloud_mode.py
@@ -3,7 +3,8 @@
 import pytest
 from ruamel import yaml
 
-from great_expectations.data_context import DataContext
+from great_expectations.data_context import BaseDataContext, DataContext
+from great_expectations.data_context.store import GeCloudStoreBackend
 from great_expectations.data_context.types.base import DataContextConfig
 from great_expectations.exceptions import DataContextError, GeCloudError
 
@@ -176,3 +177,48 @@ def test_data_context_ge_cloud_mode_with_bad_request_to_cloud_api_should_throw_e
             ge_cloud_organization_id=ge_cloud_runtime_organization_id,
             ge_cloud_access_token=ge_cloud_runtime_access_token,
         )
+
+
+@pytest.mark.cloud
+@pytest.mark.unit
+@mock.patch("requests.get")
+def test_data_context_in_cloud_mode_passes_base_url_to_store_backend(
+    mock_request,
+    ge_cloud_base_url,
+    empty_cloud_data_context_custom_base_url,
+    ge_cloud_runtime_organization_id,
+    ge_cloud_runtime_access_token,
+):
+
+    custom_base_url: str = "https://some_url.org"
+    # Ensure that the request goes through
+    mock_request.return_value.status_code = 200
+
+    context = empty_cloud_data_context_custom_base_url
+
+    # Assertions that the context fixture is set up properly
+    assert not context.ge_cloud_config.base_url == GeCloudStoreBackend.DEFAULT_BASE_URL
+    assert not context.ge_cloud_config.base_url == ge_cloud_base_url
+    assert (
+        not context.ge_cloud_config.base_url == "https://app.test.greatexpectations.io"
+    )
+
+    # The DatasourceStore should not have the default base_url or commonly used test base urls
+    assert (
+        not context._datasource_store.store_backend.config["ge_cloud_base_url"]
+        == GeCloudStoreBackend.DEFAULT_BASE_URL
+    )
+    assert (
+        not context._datasource_store.store_backend.config["ge_cloud_base_url"]
+        == ge_cloud_base_url
+    )
+    assert (
+        not context._datasource_store.store_backend.config["ge_cloud_base_url"]
+        == "https://app.test.greatexpectations.io"
+    )
+
+    # The DatasourceStore should have the custom base url set
+    assert (
+        context._datasource_store.store_backend.config["ge_cloud_base_url"]
+        == custom_base_url
+    )