Repository: aws/aws-sam-cli

Issue:
fix: use StringIO instead of BytesIO with StreamWriter
Related to https://github.com/aws/aws-sam-cli/pull/5427
#### Which issue(s) does this change fix?
N/A


#### Why is this change necessary?
With recently changed the way to write into stream to fix some issues related to encoding (see PR above). That changed caused some issues with ECRUpload class, due to discrepancy of the `write` method between `BytesIO` vs `StringIO`. `BytesIO` instance accepts byte array where `StringIO` accepts string.

#### How does it address the issue?
This resolves issue by using `StringIO` stream instead of `BytesIO`. This PR also adds some typing for the inner `stream` instance of the `StreamWrapper` class to check for other usages in the code base.


#### What side effects does this change have?
Manually running `sam local` tests to validate the change.


#### Mandatory Checklist
**PRs will only be reviewed after checklist is complete**

- [ ] Add input/output [type hints](https://docs.python.org/3/library/typing.html) to new functions/methods
- [ ] Write design document if needed ([Do I need to write a design document?](https://github.com/aws/aws-sam-cli/blob/develop/DEVELOPMENT_GUIDE.md#design-document))
- [x] Write/update unit tests
- [ ] Write/update integration tests
- [ ] Write/update functional tests if needed
- [x] `make pr` passes
- [ ] `make update-reproducible-reqs` if dependencies were changed
- [ ] Write documentation

By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0).



Discussion:

Resolving patch:
diff --git a/schema/schema.py b/schema/schema.py
--- a/schema/schema.py
+++ b/schema/schema.py
@@ -32,14 +32,17 @@ class SamCliParameterSchema:
     type: str
     description: str = ""
     default: Optional[Any] = None
+    items: Optional[str] = None
     choices: Optional[Any] = None
 
     def to_schema(self) -> Dict[str, Any]:
         """Return the JSON schema representation of the SAM CLI parameter."""
-        param = {}
+        param: Dict[str, Any] = {}
         param.update({"title": self.name, "type": self.type, "description": self.description})
         if self.default:
             param.update({"default": self.default})
+        if self.items:
+            param.update({"items": {"type": self.items}})
         if self.choices:
             param.update({"enum": self.choices})
         return param
@@ -136,7 +139,10 @@ def format_param(param: click.core.Option) -> SamCliParameterSchema:
         formatted_param_type = param_type or "string"
 
     formatted_param: SamCliParameterSchema = SamCliParameterSchema(
-        param.name or "", formatted_param_type, clean_text(param.help or "")
+        param.name or "",
+        formatted_param_type,
+        clean_text(param.help or ""),
+        items="string" if formatted_param_type == "array" else None,
     )
 
     if param.default:
@@ -150,7 +156,15 @@ def format_param(param: click.core.Option) -> SamCliParameterSchema:
 
 def get_params_from_command(cli) -> List[SamCliParameterSchema]:
     """Given a CLI object, return a list of all parameters in that CLI, formatted as SamCliParameterSchema objects."""
-    return [format_param(param) for param in cli.params if param.name and isinstance(param, click.core.Option)]
+    params_to_exclude = [
+        "config_env",  # shouldn't allow different environment from where the config is being read from
+        "config_file",  # shouldn't allow reading another file within current file
+    ]
+    return [
+        format_param(param)
+        for param in cli.params
+        if param.name and isinstance(param, click.core.Option) and param.name not in params_to_exclude
+    ]
 
 
 def retrieve_command_structure(package_name: str) -> List[SamCliCommandSchema]:


Test patch: