We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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).

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `locations/spiders/poundland.py`
Content:
```
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 FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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":

{"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"}], "after_files": [{"content": "import scrapy\n\nfrom locations.categories import Extras, apply_yes_no\nfrom locations.dict_parser import DictParser\nfrom locations.hours import OpeningHours\nfrom locations.spiders.vapestore_gb import clean_address\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\"] = 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            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\n\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                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"}]}