Repository: getmoto/moto
Pull request #6640 (2023-08-12 18:36:35)

Techdebt: Re-add an ignore for mypy
(new contributor here)

I just unrolled the [Development Installation](http://docs.getmoto.org/en/latest/docs/contributing/installation.html) guide that states python 3.x as requirement.

My workstation runs python3.11, I created a dedicated venv. When running the `make test` on master (as of writing at c8b5470e25012477f817a619e88f9ad1bea08bbe) I came across a mypy error:
```
$ mypy --install-types --non-interactive
moto/core/versions.py:6:5: error: Name "version" already defined (possibly by an import)  [no-redef]
``` 

I was able to reproduce the same issue in the CI by running the lint suite with python3.11 [with a one-line edit](https://github.com/ajoga/moto/commit/5543db1a644c553d1b3c56d56f8b584f8c1a23b0) : https://github.com/ajoga/moto/actions/runs/5842743552/job/15844189693 

Using git-bisect I found that e26cfe7dc677360f03964f33385b04a8c1c063d4 introduced this failure ; this PR offers to put it back.

kbalk: I just noticed this error as well ... it wasn't there when I started working on removing the "sure" usage from some of the tests.

Patch:
diff --git a/moto/backend_index.py b/moto/backend_index.py
index 5f57542fb..fc1508f28 100644
--- a/moto/backend_index.py
+++ b/moto/backend_index.py
@@ -114,7 +114,7 @@ backend_url_patterns = [
     ),
     (
         "meteringmarketplace",
-        re.compile("https?://metering.marketplace.(.+).amazonaws.com"),
+        re.compile("https?://metering\\.marketplace.(.+).amazonaws.com"),
     ),
     ("meteringmarketplace", re.compile("https?://aws-marketplace.(.+).amazonaws.com")),
     ("mq", re.compile("https?://mq\\.(.+)\\.amazonaws\\.com")),
diff --git a/moto/core/versions.py b/moto/core/versions.py
index 8aa754f10..16a1df52d 100644
--- a/moto/core/versions.py
+++ b/moto/core/versions.py
@@ -3,7 +3,7 @@ from moto.utilities.distutils_version import LooseVersion
 try:
     from importlib.metadata import version
 except ImportError:
-    from importlib_metadata import version
+    from importlib_metadata import version  # type: ignore[no-redef]
 
 
 RESPONSES_VERSION = version("responses")
diff --git a/moto/sagemaker/models.py b/moto/sagemaker/models.py
index a5bf3c6da..726eab895 100644
--- a/moto/sagemaker/models.py
+++ b/moto/sagemaker/models.py
@@ -3,6 +3,7 @@ import os
 import random
 import string
 from datetime import datetime
+from dateutil.tz import tzutc
 from typing import Any, Dict, List, Optional, Iterable, Union
 
 from moto.core import BaseBackend, BackendDict, BaseModel, CloudFormationModel
@@ -994,7 +995,7 @@ class ModelPackage(BaseObject):
             _type="model-package",
             _id=model_package_name,
         )
-        datetime_now = datetime.utcnow()
+        datetime_now = datetime.now(tzutc())
         self.model_package_name = model_package_name
         self.model_package_group_name = model_package_group_name
         self.model_package_version = model_package_version
@@ -2868,9 +2869,13 @@ class SageMakerModelBackend(BaseBackend):
         sort_order: Optional[str],
     ) -> List[ModelPackage]:
         if isinstance(creation_time_before, int):
-            creation_time_before_datetime = datetime.fromtimestamp(creation_time_before)
+            creation_time_before_datetime = datetime.fromtimestamp(
+                creation_time_before, tz=tzutc()
+            )
         if isinstance(creation_time_after, int):
-            creation_time_after_datetime = datetime.fromtimestamp(creation_time_after)
+            creation_time_after_datetime = datetime.fromtimestamp(
+                creation_time_after, tz=tzutc()
+            )
         if model_package_group_name is not None:
             model_package_type = "Versioned"
         model_package_summary_list = list(
diff --git a/moto/scheduler/exceptions.py b/moto/scheduler/exceptions.py
index cb126594b..0e180c2c1 100644
--- a/moto/scheduler/exceptions.py
+++ b/moto/scheduler/exceptions.py
@@ -2,6 +2,11 @@
 from moto.core.exceptions import JsonRESTError
 
 
+class ScheduleExists(JsonRESTError):
+    def __init__(self, name: str) -> None:
+        super().__init__("ConflictException", f"Schedule {name} already exists.")
+
+
 class ScheduleNotFound(JsonRESTError):
     def __init__(self) -> None:
         super().__init__("ResourceNotFoundException", "Schedule not found")
diff --git a/moto/scheduler/models.py b/moto/scheduler/models.py
index f6a559a96..090e9fc53 100644
--- a/moto/scheduler/models.py
+++ b/moto/scheduler/models.py
@@ -5,6 +5,7 @@ from moto.core import BaseBackend, BackendDict, BaseModel
 from moto.core.utils import unix_time
 from moto.utilities.tagging_service import TaggingService
 
+from .exceptions import ScheduleExists
 from .exceptions import ScheduleNotFound, ScheduleGroupNotFound
 
 
@@ -155,6 +156,8 @@ class EventBridgeSchedulerBackend(BaseBackend):
         The ClientToken parameter is not yet implemented
         """
         group = self.schedule_groups[group_name or "default"]
+        if name in group.schedules:
+            raise ScheduleExists(name)
         schedule = Schedule(
             region=self.region_name,
             account_id=self.account_id,


Test patch:
diff --git a/tests/test_scheduler/test_scheduler.py b/tests/test_scheduler/test_scheduler.py
index 9ff962a51..fea2ca458 100644
--- a/tests/test_scheduler/test_scheduler.py
+++ b/tests/test_scheduler/test_scheduler.py
@@ -144,6 +144,26 @@ def test_update_schedule(extra_kwargs):
     assert schedule["CreationDate"] != schedule["LastModificationDate"]
 
 
+@mock_scheduler
+def test_create_duplicate_schedule():
+    client = boto3.client("scheduler", region_name="us-east-1")
+    params = {
+        "ScheduleExpression": "at(2022-12-12T00:00:00)",
+        "FlexibleTimeWindow": {
+            "MaximumWindowInMinutes": 4,
+            "Mode": "FLEXIBLE",
+        },
+        "Target": {"Arn": "arn1", "RoleArn": "arn2"},
+    }
+
+    client.create_schedule(Name="schedule1", **params)
+    with pytest.raises(ClientError) as exc:
+        client.create_schedule(Name="schedule1", **params)
+    err = exc.value.response["Error"]
+    assert err["Code"] == "ConflictException"
+    assert err["Message"] == "Schedule schedule1 already exists."
+
+
 @mock_scheduler
 def test_get_schedule_for_unknown_group():
     client = boto3.client("scheduler", region_name="eu-west-1")