prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Poundland spider address parsing issue
  The addr:street_address field returned by the poundland.py spider is sometimes broken, giving results such as:
  `"addr:street_address": "5, 6, -, 5, 8,  , T, a, f, f,  , S, t, r, e, e, t"`
  The problem is caused by line 20 in the code:
  ` item["street_address"] = ", ".join(filter(None, store["address"].get("line")))`
  where is is assumed that "line" from the scraped JSON  will be an array of values. But it is sometimes "line" is just a single string. When this happens, the string itself is split into individual characters, giving results like the one above.
  
  I guess that before applying that code we should test whether "line" is a single string. I don't think I know enough python to know the best way to fix this, and a quick Google suggests there may be a difference between Python 2 and Python 3 (which would make it difficult for me to test any solutions).
  
  </issue>
  <code>
  [start of locations/spiders/poundland.py]
  1 import scrapy
  2 
  3 from locations.dict_parser import DictParser
  4 from locations.hours import OpeningHours
  5 
  6 
  7 class PoundlandSpider(scrapy.Spider):
  8     name = "poundland"
  9     item_attributes = {"brand": "Poundland", "brand_wikidata": "Q1434528"}
  10     start_urls = [
  11         "https://www.poundland.co.uk/rest/poundland/V1/locator/?searchCriteria[scope]=store-locator&searchCriteria[current_page]=1&searchCriteria[page_size]=10000"
  12     ]
  13     custom_settings = {"DEFAULT_REQUEST_HEADERS": {"Accept": "application/json"}}
  14 
  15     def parse(self, response):
  16         # We may have to handle pagination at some point
  17         for store in response.json()["locations"]:
  18             item = DictParser.parse(store)
  19 
  20             item["street_address"] = ", ".join(filter(None, store["address"].get("line")))
  21 
  22             # "store_id" seems to be a better ref than "id"
  23             item["ref"] = store.get("store_id")
  24             item["website"] = "https://www.poundland.co.uk/store-finder/store_page/view/id/" + item["ref"] + "/"
  25 
  26             oh = OpeningHours()
  27             for rule in store["opening_hours"]:
  28                 if rule["hours"] == "Closed":
  29                     continue
  30                 open_time, close_time = rule["hours"].split(" - ")
  31                 oh.add_range(rule["day"][:2], open_time, close_time)
  32 
  33             item["opening_hours"] = oh.as_opening_hours()
  34 
  35             item["extras"] = {}
  36             item["extras"]["atm"] = "yes" if store.get("atm") == "1" else "no"
  37             item["extras"]["icestore"] = "yes" if store.get("icestore") == "1" else "no"
  38 
  39             if store["is_pep_co_only"] == "1":
  40                 item["brand"] = "Pep&Co"
  41                 item["brand_wikidata"] = "Q24908166"
  42             else:
  43                 if store.get("pepshopinshop") == "1":
  44                     # Pep and Poundland at this location
  45                     pep = item.copy()
  46 
  47                     pep["ref"] = pep["ref"] + "_pep"
  48 
  49                     pep["brand"] = "Pep&Co"
  50                     pep["brand_wikidata"] = "Q24908166"
  51 
  52                     pep["located_in"] = self.item_attributes["brand"]
  53                     pep["located_in_wikidata"] = self.item_attributes["brand_wikidata"]
  54 
  55                     yield pep
  56 
  57             yield item
  58
  [end of locations/spiders/poundland.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/locations/spiders/poundland.py b/locations/spiders/poundland.py
  --- a/locations/spiders/poundland.py
  +++ b/locations/spiders/poundland.py
  @@ -1,7 +1,9 @@
   import scrapy
   
  +from locations.categories import Extras, apply_yes_no
   from locations.dict_parser import DictParser
   from locations.hours import OpeningHours
  +from locations.spiders.vapestore_gb import clean_address
   
   
   class PoundlandSpider(scrapy.Spider):
  @@ -17,7 +19,7 @@
           for store in response.json()["locations"]:
               item = DictParser.parse(store)
   
  -            item["street_address"] = ", ".join(filter(None, store["address"].get("line")))
  +            item["street_address"] = clean_address(store["address"].get("line"))
   
               # "store_id" seems to be a better ref than "id"
               item["ref"] = store.get("store_id")
  @@ -30,10 +32,9 @@
                   open_time, close_time = rule["hours"].split(" - ")
                   oh.add_range(rule["day"][:2], open_time, close_time)
   
  -            item["opening_hours"] = oh.as_opening_hours()
  +            item["opening_hours"] = oh
   
  -            item["extras"] = {}
  -            item["extras"]["atm"] = "yes" if store.get("atm") == "1" else "no"
  +            apply_yes_no(Extras.ATM, item, store.get("atm") == "1")
               item["extras"]["icestore"] = "yes" if store.get("icestore") == "1" else "no"
   
               if store["is_pep_co_only"] == "1":
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/poundland.py b/locations/spiders/poundland.py\n--- a/locations/spiders/poundland.py\n+++ b/locations/spiders/poundland.py\n@@ -1,7 +1,9 @@\n import scrapy\n \n+from locations.categories import Extras, apply_yes_no\n from locations.dict_parser import DictParser\n from locations.hours import OpeningHours\n+from locations.spiders.vapestore_gb import clean_address\n \n \n class PoundlandSpider(scrapy.Spider):\n@@ -17,7 +19,7 @@\n         for store in response.json()[\"locations\"]:\n             item = DictParser.parse(store)\n \n-            item[\"street_address\"] = \", \".join(filter(None, store[\"address\"].get(\"line\")))\n+            item[\"street_address\"] = clean_address(store[\"address\"].get(\"line\"))\n \n             # \"store_id\" seems to be a better ref than \"id\"\n             item[\"ref\"] = store.get(\"store_id\")\n@@ -30,10 +32,9 @@\n                 open_time, close_time = rule[\"hours\"].split(\" - \")\n                 oh.add_range(rule[\"day\"][:2], open_time, close_time)\n \n-            item[\"opening_hours\"] = oh.as_opening_hours()\n+            item[\"opening_hours\"] = oh\n \n-            item[\"extras\"] = {}\n-            item[\"extras\"][\"atm\"] = \"yes\" if store.get(\"atm\") == \"1\" else \"no\"\n+            apply_yes_no(Extras.ATM, item, store.get(\"atm\") == \"1\")\n             item[\"extras\"][\"icestore\"] = \"yes\" if store.get(\"icestore\") == \"1\" else \"no\"\n \n             if store[\"is_pep_co_only\"] == \"1\":\n", "issue": "Poundland spider address parsing issue\nThe addr:street_address field returned by the poundland.py spider is sometimes broken, giving results such as:\r\n`\"addr:street_address\": \"5, 6, -, 5, 8,  , T, a, f, f,  , S, t, r, e, e, t\"`\r\nThe problem is caused by line 20 in the code:\r\n` item[\"street_address\"] = \", \".join(filter(None, store[\"address\"].get(\"line\")))`\r\nwhere is is assumed that \"line\" from the scraped JSON  will be an array of values. But it is sometimes \"line\" is just a single string. When this happens, the string itself is split into individual characters, giving results like the one above.\r\n\r\nI guess that before applying that code we should test whether \"line\" is a single string. I don't think I know enough python to know the best way to fix this, and a quick Google suggests there may be a difference between Python 2 and Python 3 (which would make it difficult for me to test any solutions).\n", "before_files": [{"content": "import scrapy\n\nfrom locations.dict_parser import DictParser\nfrom locations.hours import OpeningHours\n\n\nclass PoundlandSpider(scrapy.Spider):\n    name = \"poundland\"\n    item_attributes = {\"brand\": \"Poundland\", \"brand_wikidata\": \"Q1434528\"}\n    start_urls = [\n        \"https://www.poundland.co.uk/rest/poundland/V1/locator/?searchCriteria[scope]=store-locator&searchCriteria[current_page]=1&searchCriteria[page_size]=10000\"\n    ]\n    custom_settings = {\"DEFAULT_REQUEST_HEADERS\": {\"Accept\": \"application/json\"}}\n\n    def parse(self, response):\n        # We may have to handle pagination at some point\n        for store in response.json()[\"locations\"]:\n            item = DictParser.parse(store)\n\n            item[\"street_address\"] = \", \".join(filter(None, store[\"address\"].get(\"line\")))\n\n            # \"store_id\" seems to be a better ref than \"id\"\n            item[\"ref\"] = store.get(\"store_id\")\n            item[\"website\"] = \"https://www.poundland.co.uk/store-finder/store_page/view/id/\" + item[\"ref\"] + \"/\"\n\n            oh = OpeningHours()\n            for rule in store[\"opening_hours\"]:\n                if rule[\"hours\"] == \"Closed\":\n                    continue\n                open_time, close_time = rule[\"hours\"].split(\" - \")\n                oh.add_range(rule[\"day\"][:2], open_time, close_time)\n\n            item[\"opening_hours\"] = oh.as_opening_hours()\n\n            item[\"extras\"] = {}\n            item[\"extras\"][\"atm\"] = \"yes\" if store.get(\"atm\") == \"1\" else \"no\"\n            item[\"extras\"][\"icestore\"] = \"yes\" if store.get(\"icestore\") == \"1\" else \"no\"\n\n            if store[\"is_pep_co_only\"] == \"1\":\n                item[\"brand\"] = \"Pep&Co\"\n                item[\"brand_wikidata\"] = \"Q24908166\"\n            else:\n                if store.get(\"pepshopinshop\") == \"1\":\n                    # Pep and Poundland at this location\n                    pep = item.copy()\n\n                    pep[\"ref\"] = pep[\"ref\"] + \"_pep\"\n\n                    pep[\"brand\"] = \"Pep&Co\"\n                    pep[\"brand_wikidata\"] = \"Q24908166\"\n\n                    pep[\"located_in\"] = self.item_attributes[\"brand\"]\n                    pep[\"located_in_wikidata\"] = self.item_attributes[\"brand_wikidata\"]\n\n                    yield pep\n\n            yield item\n", "path": "locations/spiders/poundland.py"}]}