prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Can't configure source without arguments
  Hello Team,
  I'm trying to configure into HomeAssistant the source that I added Mamirolle info, but I have argument issues.
  
  `args` is marked `required`, so if none is passed, the configuration is invalid.
  
  ```
  Invalid config for [waste_collection_schedule]: required key not provided @ data['waste_collection_schedule']['sources'][0]['args']. Got None. (See /config/configuration.yaml, line 27). 
  ```
  
  If a dummy argument is passed. The configuration is valid but the source setup fails.
  ```
  Error during setup of component waste_collection_schedule
  
  Traceback (most recent call last):
    File "/usr/src/homeassistant/homeassistant/setup.py", line 288, in _async_setup_component
      result = await task
               ^^^^^^^^^^
    File "/config/custom_components/waste_collection_schedule/__init__.py", line 109, in async_setup
      api.add_source_shell(
    File "/config/custom_components/waste_collection_schedule/__init__.py", line 202, in add_source_shell
      SourceShell.create(
    File "/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py", line 196, in create
      source = source_module.Source(**source_args)  # type: ignore
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  TypeError: Source() takes no arguments
  ```
  I understand that we want the configuration to fail early but the real error will still be seen only when the source is actually instantiated. Because of that I think the arguments shouldn't be required.
  
  What do you think about this?
  
  </issue>
  <code>
  [start of custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py]
  1 import datetime
  2 
  3 import requests
  4 from bs4 import BeautifulSoup
  5 from waste_collection_schedule import Collection
  6 
  7 TITLE = "Mairie de Mamirolle"
  8 DESCRIPTION = "Source script for mamirolle.info"
  9 COUNTRY = "fr"
  10 URL = "http://mamirolle.info/"
  11 
  12 TEST_CASES = {"TestSource": {}}
  13 
  14 ICON_MAP = {
  15     "Poubelle grise": "mdi:trash-can",
  16     "Poubelle jaune": "mdi:recycle",
  17 }
  18 
  19 MONTH_NAMES = [
  20     "janvier",
  21     "février",
  22     "mars",
  23     "avril",
  24     "mai",
  25     "juin",
  26     "juillet",
  27     "août",
  28     "septembre",
  29     "octobre",
  30     "novembre",
  31     "décembre",
  32 ]
  33 
  34 
  35 class Source:
  36     def fetch(self):
  37         now = datetime.datetime.now()
  38         # get list of regions and weblinks
  39         page = requests.get(URL)
  40         # A lenient HTML parser is need
  41         soup = BeautifulSoup(page.text.replace("<![endif]", ""), "html.parser")
  42         trash_domestic = soup.find("i", class_="poubelle-grise")
  43         _, day, month = trash_domestic.next_sibling.string.split()
  44         date_domestic = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
  45         if date_domestic < now.date():
  46             date_domestic = date_domestic.replace(year=date_domestic.year + 1)
  47 
  48         trash_recycle = soup.find("i", class_="poubelle-jaune")
  49         _, day, month = trash_recycle.next_sibling.string.split()
  50         date_recycle = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
  51         if date_recycle < now.date():
  52             date_recycle = date_recycle.replace(year=date_recycle.year + 1)
  53 
  54         entries = [
  55             Collection(
  56                 date=date_domestic,
  57                 t="Poubelle grise",
  58                 icon=ICON_MAP.get("Poubelle grise"),
  59             ),
  60             Collection(
  61                 date=date_recycle,
  62                 t="Poubelle jaune",
  63                 icon=ICON_MAP.get("Poubelle jaune"),
  64             ),
  65         ]  # List that holds collection schedule
  66 
  67         return entries
  68
  [end of custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
  --- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
  +++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py
  @@ -9,7 +9,12 @@
   COUNTRY = "fr"
   URL = "http://mamirolle.info/"
   
  -TEST_CASES = {"TestSource": {}}
  +TEST_CASES = {
  +    "TestSource": {},
  +    "IgnoredArgument": {
  +        "_": ""
  +    }
  +}
   
   ICON_MAP = {
       "Poubelle grise": "mdi:trash-can",
  @@ -33,6 +38,9 @@
   
   
   class Source:
  +    def __init__(self, _=None):
  +        pass
  +
       def fetch(self):
           now = datetime.datetime.now()
           # get list of regions and weblinks
  @@ -40,28 +48,19 @@
           # A lenient HTML parser is need
           soup = BeautifulSoup(page.text.replace("<![endif]", ""), "html.parser")
           trash_domestic = soup.find("i", class_="poubelle-grise")
  -        _, day, month = trash_domestic.next_sibling.string.split()
  -        date_domestic = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
  -        if date_domestic < now.date():
  -            date_domestic = date_domestic.replace(year=date_domestic.year + 1)
  -
           trash_recycle = soup.find("i", class_="poubelle-jaune")
  -        _, day, month = trash_recycle.next_sibling.string.split()
  -        date_recycle = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()
  -        if date_recycle < now.date():
  -            date_recycle = date_recycle.replace(year=date_recycle.year + 1)
   
  -        entries = [
  -            Collection(
  -                date=date_domestic,
  -                t="Poubelle grise",
  -                icon=ICON_MAP.get("Poubelle grise"),
  -            ),
  -            Collection(
  -                date=date_recycle,
  -                t="Poubelle jaune",
  -                icon=ICON_MAP.get("Poubelle jaune"),
  -            ),
  -        ]  # List that holds collection schedule
  +        entries = []  # List that holds collection schedule
  +        for trash, label in [(trash_domestic, "Poubelle grise"), (trash_recycle, "Poubelle jaune")]:
  +            _, day, month = trash.next_sibling.string.split()
  +            date = now.replace(month=MONTH_NAMES.index(month) + 1, day=int(day)).date()
  +            if date < now.date():
  +                date = date.replace(year=date.year + 1)
  +
  +            entries.append(Collection(
  +                date=date,
  +                t=label,
  +                icon=ICON_MAP.get(label),
  +            ))
   
           return entries
  
verification_info: {"golden_diff": "diff --git a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py\n--- a/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py\n+++ b/custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py\n@@ -9,7 +9,12 @@\n COUNTRY = \"fr\"\n URL = \"http://mamirolle.info/\"\n \n-TEST_CASES = {\"TestSource\": {}}\n+TEST_CASES = {\n+    \"TestSource\": {},\n+    \"IgnoredArgument\": {\n+        \"_\": \"\"\n+    }\n+}\n \n ICON_MAP = {\n     \"Poubelle grise\": \"mdi:trash-can\",\n@@ -33,6 +38,9 @@\n \n \n class Source:\n+    def __init__(self, _=None):\n+        pass\n+\n     def fetch(self):\n         now = datetime.datetime.now()\n         # get list of regions and weblinks\n@@ -40,28 +48,19 @@\n         # A lenient HTML parser is need\n         soup = BeautifulSoup(page.text.replace(\"<![endif]\", \"\"), \"html.parser\")\n         trash_domestic = soup.find(\"i\", class_=\"poubelle-grise\")\n-        _, day, month = trash_domestic.next_sibling.string.split()\n-        date_domestic = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()\n-        if date_domestic < now.date():\n-            date_domestic = date_domestic.replace(year=date_domestic.year + 1)\n-\n         trash_recycle = soup.find(\"i\", class_=\"poubelle-jaune\")\n-        _, day, month = trash_recycle.next_sibling.string.split()\n-        date_recycle = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()\n-        if date_recycle < now.date():\n-            date_recycle = date_recycle.replace(year=date_recycle.year + 1)\n \n-        entries = [\n-            Collection(\n-                date=date_domestic,\n-                t=\"Poubelle grise\",\n-                icon=ICON_MAP.get(\"Poubelle grise\"),\n-            ),\n-            Collection(\n-                date=date_recycle,\n-                t=\"Poubelle jaune\",\n-                icon=ICON_MAP.get(\"Poubelle jaune\"),\n-            ),\n-        ]  # List that holds collection schedule\n+        entries = []  # List that holds collection schedule\n+        for trash, label in [(trash_domestic, \"Poubelle grise\"), (trash_recycle, \"Poubelle jaune\")]:\n+            _, day, month = trash.next_sibling.string.split()\n+            date = now.replace(month=MONTH_NAMES.index(month) + 1, day=int(day)).date()\n+            if date < now.date():\n+                date = date.replace(year=date.year + 1)\n+\n+            entries.append(Collection(\n+                date=date,\n+                t=label,\n+                icon=ICON_MAP.get(label),\n+            ))\n \n         return entries\n", "issue": "Can't configure source without arguments\nHello Team,\r\nI'm trying to configure into HomeAssistant the source that I added Mamirolle info, but I have argument issues.\r\n\r\n`args` is marked `required`, so if none is passed, the configuration is invalid.\r\n\r\n```\r\nInvalid config for [waste_collection_schedule]: required key not provided @ data['waste_collection_schedule']['sources'][0]['args']. Got None. (See /config/configuration.yaml, line 27). \r\n```\r\n\r\nIf a dummy argument is passed. The configuration is valid but the source setup fails.\r\n```\r\nError during setup of component waste_collection_schedule\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/src/homeassistant/homeassistant/setup.py\", line 288, in _async_setup_component\r\n    result = await task\r\n             ^^^^^^^^^^\r\n  File \"/config/custom_components/waste_collection_schedule/__init__.py\", line 109, in async_setup\r\n    api.add_source_shell(\r\n  File \"/config/custom_components/waste_collection_schedule/__init__.py\", line 202, in add_source_shell\r\n    SourceShell.create(\r\n  File \"/config/custom_components/waste_collection_schedule/waste_collection_schedule/source_shell.py\", line 196, in create\r\n    source = source_module.Source(**source_args)  # type: ignore\r\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nTypeError: Source() takes no arguments\r\n```\r\nI understand that we want the configuration to fail early but the real error will still be seen only when the source is actually instantiated. Because of that I think the arguments shouldn't be required.\r\n\r\nWhat do you think about this?\n", "before_files": [{"content": "import datetime\n\nimport requests\nfrom bs4 import BeautifulSoup\nfrom waste_collection_schedule import Collection\n\nTITLE = \"Mairie de Mamirolle\"\nDESCRIPTION = \"Source script for mamirolle.info\"\nCOUNTRY = \"fr\"\nURL = \"http://mamirolle.info/\"\n\nTEST_CASES = {\"TestSource\": {}}\n\nICON_MAP = {\n    \"Poubelle grise\": \"mdi:trash-can\",\n    \"Poubelle jaune\": \"mdi:recycle\",\n}\n\nMONTH_NAMES = [\n    \"janvier\",\n    \"f\u00e9vrier\",\n    \"mars\",\n    \"avril\",\n    \"mai\",\n    \"juin\",\n    \"juillet\",\n    \"ao\u00fbt\",\n    \"septembre\",\n    \"octobre\",\n    \"novembre\",\n    \"d\u00e9cembre\",\n]\n\n\nclass Source:\n    def fetch(self):\n        now = datetime.datetime.now()\n        # get list of regions and weblinks\n        page = requests.get(URL)\n        # A lenient HTML parser is need\n        soup = BeautifulSoup(page.text.replace(\"<![endif]\", \"\"), \"html.parser\")\n        trash_domestic = soup.find(\"i\", class_=\"poubelle-grise\")\n        _, day, month = trash_domestic.next_sibling.string.split()\n        date_domestic = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()\n        if date_domestic < now.date():\n            date_domestic = date_domestic.replace(year=date_domestic.year + 1)\n\n        trash_recycle = soup.find(\"i\", class_=\"poubelle-jaune\")\n        _, day, month = trash_recycle.next_sibling.string.split()\n        date_recycle = now.replace(month=MONTH_NAMES.index(month), day=int(day)).date()\n        if date_recycle < now.date():\n            date_recycle = date_recycle.replace(year=date_recycle.year + 1)\n\n        entries = [\n            Collection(\n                date=date_domestic,\n                t=\"Poubelle grise\",\n                icon=ICON_MAP.get(\"Poubelle grise\"),\n            ),\n            Collection(\n                date=date_recycle,\n                t=\"Poubelle jaune\",\n                icon=ICON_MAP.get(\"Poubelle jaune\"),\n            ),\n        ]  # List that holds collection schedule\n\n        return entries\n", "path": "custom_components/waste_collection_schedule/waste_collection_schedule/source/mamirolle_info.py"}]}