Repository: great-expectations/great_expectations

Issue:
PandasExecutionEngine instantiation fails when passing boto3_options
**Description**
When attempting to customize PandasExecutionEngine by passing a boto3_options map, instantiation fails.

**To Reproduce**
Steps to reproduce the behavior:
1. Configure a connector with pandas execution engine and custom boto3 parameters, as follows:
```yaml
my_s3_data_source:
   class_name: Datasource
   execution_engine:
     class_name: PandasExecutionEngine
     boto3_options:
       aws_access_key_id: foo
       aws_secret_access_key: bar
       endpoint_url: http://localhost:4566
   data_connectors:
     test: 
       class_name: ConfiguredAssetS3DataConnector
       bucket: my_bucket
       boto3_options:
         aws_access_key_id: foo
         aws_secret_access_key: bar
         endpoint_url: http://localhost:4566
``` 
2. get datasource from context and perform self check
```python
import great_expectations as ge
context = ge.data_context.DataContext()
ds = context.get_datasource("my_s3_data_source")
ds.self_check()
```
3. Raises `DatasourceInitializationError`
```text
DatasourceInitializationError: Cannot initialize datasource my_s3_data_source, error: Couldn't instantiate class: PandasExecutionEngine with config: 
	boto3_options		{'aws_access_key_id': 'foo', 'aws_secret_access_key': 'bar', 'endpoint_url': 'http://localhost:30566'}
 
__init__() got an unexpected keyword argument 'boto3_options'

```

**Expected behavior**
Successful instantiation of a pandas execution engine.

**Environment (please complete the following information):**
 - Operating System: MacOS
 - Great Expectations Version: 0.13.19



Discussion:

Resolving patch:
diff --git a/great_expectations/execution_engine/pandas_execution_engine.py b/great_expectations/execution_engine/pandas_execution_engine.py
--- a/great_expectations/execution_engine/pandas_execution_engine.py
+++ b/great_expectations/execution_engine/pandas_execution_engine.py
@@ -74,10 +74,10 @@ class PandasExecutionEngine(ExecutionEngine):
     }
 
     def __init__(self, *args, **kwargs):
-        self.discard_subset_failing_expectations = kwargs.get(
+        self.discard_subset_failing_expectations = kwargs.pop(
             "discard_subset_failing_expectations", False
         )
-        boto3_options: dict = kwargs.get("boto3_options", {})
+        boto3_options: dict = kwargs.pop("boto3_options", {})
 
         # Try initializing boto3 client. If unsuccessful, we'll catch it when/if a S3BatchSpec is passed in.
         try:


Test patch:
diff --git a/tests/execution_engine/test_pandas_execution_engine.py b/tests/execution_engine/test_pandas_execution_engine.py
--- a/tests/execution_engine/test_pandas_execution_engine.py
+++ b/tests/execution_engine/test_pandas_execution_engine.py
@@ -28,6 +28,20 @@
 from tests.expectations.test_util import get_table_columns_metric
 
 
+def test_constructor():
+    # default instantiation
+    PandasExecutionEngine()
+
+    # instantiation with custom parameters
+    engine = PandasExecutionEngine(discard_subset_failing_expectations=True)
+    assert "discard_subset_failing_expectations" in engine.config
+    assert engine.config.get("discard_subset_failing_expectations") is True
+    custom_boto3_options = {"region_name": "us-east-1"}
+    engine = PandasExecutionEngine(boto3_options=custom_boto3_options)
+    assert "boto3_options" in engine.config
+    assert engine.config.get("boto3_options")["region_name"] == "us-east-1"
+
+
 def test_reader_fn():
     engine = PandasExecutionEngine()