We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Can't un-pickle a `HolidayBase`
Seems that after a holidays class, e.g. `holidays.UnitedStates()` is used once, it can't be un-pickled.

For example, this snippet:

```python
import holidays
import pickle
from datetime import datetime

# Works:
us_holidays = holidays.UnitedStates()
us_holidays_ = pickle.loads(pickle.dumps(us_holidays))
b = datetime.fromisoformat("2020-01-01") in us_holidays_

# Fails:
us_holidays = holidays.UnitedStates()
b = datetime.fromisoformat("2020-01-01") in us_holidays
dump = pickle.dumps(us_holidays)
pickle.loads(dump)  # <- exception
```

Raises the following exception from the last line:
```
~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __setitem__(self, key, value)
    116
    117     def __setitem__(self, key, value):
--> 118         if key in self:
    119             if self.get(key).find(value) < 0 \
    120                     and value.find(self.get(key)) < 0:

~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __contains__(self, key)
     73
     74     def __contains__(self, key):
---> 75         return dict.__contains__(self, self.__keytransform__(key))
     76
     77     def __getitem__(self, key):

~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __keytransform__(self, key)
     67             raise TypeError("Cannot convert type '%s' to date." % type(key))
     68
---> 69         if self.expand and key.year not in self.years:
     70             self.years.add(key.year)
     71             self._populate(key.year)
```

The `expand` attribute is set by `__init__`, but it's not there during deserialization via unpickling.
I think it's because the `HolidayBase` inherits from dict and there's some weirdness there - it seems to first populate the dict in the deserialized object and only then sets the attributes from the state. But since `HolidayBase` overrides `__setitem__` and in this override it's using state attributes that weren't yet set on the object, the `expand` attribute is missing.

Tested with `holidays=='0.10.4'`.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `holidays/holiday_base.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 #  python-holidays
4 #  ---------------
5 #  A fast, efficient Python library for generating country, province and state
6 #  specific sets of holidays on the fly. It aims to make determining whether a
7 #  specific date is a holiday as fast and flexible as possible.
8 #
9 #  Author:  ryanss <ryanssdev@icloud.com> (c) 2014-2017
10 #           dr-prodigy <maurizio.montel@gmail.com> (c) 2017-2021
11 #  Website: https://github.com/dr-prodigy/python-holidays
12 #  License: MIT (see LICENSE file)
13 
14 from datetime import timedelta, datetime, date
15 
16 import six
17 from dateutil.parser import parse
18 
19 
20 class HolidayBase(dict):
21     PROVINCES = []
22 
23     def __init__(
24         self, years=[], expand=True, observed=True, prov=None, state=None
25     ):
26         self.observed = observed
27         self.expand = expand
28         if isinstance(years, int):
29             years = [
30                 years,
31             ]
32         self.years = set(years)
33         if not getattr(self, "prov", False):
34             self.prov = prov
35         self.state = state
36         for year in list(self.years):
37             self._populate(year)
38 
39     def __setattr__(self, key, value):
40         if key == "observed" and len(self) > 0:
41             dict.__setattr__(self, key, value)
42             if value is True:
43                 # Add (Observed) dates
44                 years = list(self.years)
45                 self.years = set()
46                 self.clear()
47                 for year in years:
48                     self._populate(year)
49             else:
50                 # Remove (Observed) dates
51                 for k, v in list(self.items()):
52                     if v.find("Observed") >= 0:
53                         del self[k]
54         else:
55             return dict.__setattr__(self, key, value)
56 
57     def __keytransform__(self, key):
58         if isinstance(key, datetime):
59             key = key.date()
60         elif isinstance(key, date):
61             key = key
62         elif isinstance(key, int) or isinstance(key, float):
63             key = datetime.utcfromtimestamp(key).date()
64         elif isinstance(key, six.string_types):
65             try:
66                 key = parse(key).date()
67             except (ValueError, OverflowError):
68                 raise ValueError("Cannot parse date from string '%s'" % key)
69         else:
70             raise TypeError("Cannot convert type '%s' to date." % type(key))
71 
72         if self.expand and key.year not in self.years:
73             self.years.add(key.year)
74             self._populate(key.year)
75         return key
76 
77     def __contains__(self, key):
78         return dict.__contains__(self, self.__keytransform__(key))
79 
80     def __getitem__(self, key):
81         if isinstance(key, slice):
82             if not key.start or not key.stop:
83                 raise ValueError("Both start and stop must be given.")
84 
85             start = self.__keytransform__(key.start)
86             stop = self.__keytransform__(key.stop)
87 
88             if key.step is None:
89                 step = 1
90             elif isinstance(key.step, timedelta):
91                 step = key.step.days
92             elif isinstance(key.step, int):
93                 step = key.step
94             else:
95                 raise TypeError(
96                     "Cannot convert type '%s' to int." % type(key.step)
97                 )
98 
99             if step == 0:
100                 raise ValueError("Step value must not be zero.")
101 
102             date_diff = stop - start
103             if date_diff.days < 0 <= step or date_diff.days >= 0 > step:
104                 step *= -1
105 
106             days_in_range = []
107             for delta_days in range(0, date_diff.days, step):
108                 day = start + timedelta(days=delta_days)
109                 try:
110                     dict.__getitem__(self, day)
111                     days_in_range.append(day)
112                 except KeyError:
113                     pass
114             return days_in_range
115         return dict.__getitem__(self, self.__keytransform__(key))
116 
117     def __setitem__(self, key, value):
118         if key in self:
119             if self.get(key).find(value) < 0 and value.find(self.get(key)) < 0:
120                 value = "%s, %s" % (value, self.get(key))
121             else:
122                 value = self.get(key)
123         return dict.__setitem__(self, self.__keytransform__(key), value)
124 
125     def update(self, *args):
126         args = list(args)
127         for arg in args:
128             if isinstance(arg, dict):
129                 for key, value in list(arg.items()):
130                     self[key] = value
131             elif isinstance(arg, list):
132                 for item in arg:
133                     self[item] = "Holiday"
134             else:
135                 self[arg] = "Holiday"
136 
137     def append(self, *args):
138         return self.update(*args)
139 
140     def get(self, key, default=None):
141         return dict.get(self, self.__keytransform__(key), default)
142 
143     def get_list(self, key):
144         return [h for h in self.get(key, "").split(", ") if h]
145 
146     def get_named(self, name):
147         # find all dates matching provided name (accepting partial
148         # strings too, case insensitive), returning them in a list
149         original_expand = self.expand
150         self.expand = False
151         matches = [key for key in self if name.lower() in self[key].lower()]
152         self.expand = original_expand
153         return matches
154 
155     def pop(self, key, default=None):
156         if default is None:
157             return dict.pop(self, self.__keytransform__(key))
158         return dict.pop(self, self.__keytransform__(key), default)
159 
160     def pop_named(self, name):
161         to_pop = self.get_named(name)
162         if not to_pop:
163             raise KeyError(name)
164         for key in to_pop:
165             self.pop(key)
166         return to_pop
167 
168     def __eq__(self, other):
169         return dict.__eq__(self, other) and self.__dict__ == other.__dict__
170 
171     def __ne__(self, other):
172         return dict.__ne__(self, other) or self.__dict__ != other.__dict__
173 
174     def __add__(self, other):
175         if isinstance(other, int) and other == 0:
176             # Required to sum() list of holidays
177             # sum([h1, h2]) is equivalent to (0 + h1 + h2)
178             return self
179         elif not isinstance(other, HolidayBase):
180             raise TypeError()
181         HolidaySum = createHolidaySum(self, other)
182         country = getattr(self, "country", None) or getattr(
183             other, "country", None
184         )
185         if self.country and other.country and self.country != other.country:
186             c1 = self.country
187             if not isinstance(c1, list):
188                 c1 = [c1]
189             c2 = other.country
190             if not isinstance(c2, list):
191                 c2 = [c2]
192             country = c1 + c2
193         prov = getattr(self, "prov", None) or getattr(other, "prov", None)
194         if self.prov and other.prov and self.prov != other.prov:
195             p1 = self.prov if isinstance(self.prov, list) else [self.prov]
196             p2 = other.prov if isinstance(other.prov, list) else [other.prov]
197             prov = p1 + p2
198         return HolidaySum(
199             years=(self.years | other.years),
200             expand=(self.expand or other.expand),
201             observed=(self.observed or other.observed),
202             country=country,
203             prov=prov,
204         )
205 
206     def __radd__(self, other):
207         return self.__add__(other)
208 
209     def _populate(self, year):
210         pass
211 
212 
213 def createHolidaySum(h1, h2):
214     class HolidaySum(HolidayBase):
215         def __init__(self, country, **kwargs):
216             self.country = country
217             self.holidays = []
218             if getattr(h1, "holidays", False):
219                 for h in h1.holidays:
220                     self.holidays.append(h)
221             else:
222                 self.holidays.append(h1)
223             if getattr(h2, "holidays", False):
224                 for h in h2.holidays:
225                     self.holidays.append(h)
226             else:
227                 self.holidays.append(h2)
228             HolidayBase.__init__(self, **kwargs)
229 
230         def _populate(self, year):
231             for h in self.holidays[::-1]:
232                 h._populate(year)
233                 self.update(h)
234 
235     return HolidaySum
236
```
--- 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/holidays/holiday_base.py b/holidays/holiday_base.py
--- a/holidays/holiday_base.py
+++ b/holidays/holiday_base.py
@@ -209,6 +209,9 @@
     def _populate(self, year):
         pass
 
+    def __reduce__(self):
+        return super(HolidayBase, self).__reduce__()
+
 
 def createHolidaySum(h1, h2):
     class HolidaySum(HolidayBase):

{"golden_diff": "diff --git a/holidays/holiday_base.py b/holidays/holiday_base.py\n--- a/holidays/holiday_base.py\n+++ b/holidays/holiday_base.py\n@@ -209,6 +209,9 @@\n     def _populate(self, year):\n         pass\n \n+    def __reduce__(self):\n+        return super(HolidayBase, self).__reduce__()\n+\n \n def createHolidaySum(h1, h2):\n     class HolidaySum(HolidayBase):\n", "issue": "Can't un-pickle a `HolidayBase`\nSeems that after a holidays class, e.g. `holidays.UnitedStates()` is used once, it can't be un-pickled.\r\n\r\nFor example, this snippet:\r\n\r\n```python\r\nimport holidays\r\nimport pickle\r\nfrom datetime import datetime\r\n\r\n# Works:\r\nus_holidays = holidays.UnitedStates()\r\nus_holidays_ = pickle.loads(pickle.dumps(us_holidays))\r\nb = datetime.fromisoformat(\"2020-01-01\") in us_holidays_\r\n\r\n# Fails:\r\nus_holidays = holidays.UnitedStates()\r\nb = datetime.fromisoformat(\"2020-01-01\") in us_holidays\r\ndump = pickle.dumps(us_holidays)\r\npickle.loads(dump)  # <- exception\r\n```\r\n\r\nRaises the following exception from the last line:\r\n```\r\n~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __setitem__(self, key, value)\r\n    116\r\n    117     def __setitem__(self, key, value):\r\n--> 118         if key in self:\r\n    119             if self.get(key).find(value) < 0 \\\r\n    120                     and value.find(self.get(key)) < 0:\r\n\r\n~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __contains__(self, key)\r\n     73\r\n     74     def __contains__(self, key):\r\n---> 75         return dict.__contains__(self, self.__keytransform__(key))\r\n     76\r\n     77     def __getitem__(self, key):\r\n\r\n~/.local/share/virtualenvs/sibylla-v2-LxBhzJgn/lib/python3.8/site-packages/holidays/holiday_base.py in __keytransform__(self, key)\r\n     67             raise TypeError(\"Cannot convert type '%s' to date.\" % type(key))\r\n     68\r\n---> 69         if self.expand and key.year not in self.years:\r\n     70             self.years.add(key.year)\r\n     71             self._populate(key.year)\r\n```\r\n\r\nThe `expand` attribute is set by `__init__`, but it's not there during deserialization via unpickling.\r\nI think it's because the `HolidayBase` inherits from dict and there's some weirdness there - it seems to first populate the dict in the deserialized object and only then sets the attributes from the state. But since `HolidayBase` overrides `__setitem__` and in this override it's using state attributes that weren't yet set on the object, the `expand` attribute is missing.\r\n\r\nTested with `holidays=='0.10.4'`.\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n#  python-holidays\n#  ---------------\n#  A fast, efficient Python library for generating country, province and state\n#  specific sets of holidays on the fly. It aims to make determining whether a\n#  specific date is a holiday as fast and flexible as possible.\n#\n#  Author:  ryanss <ryanssdev@icloud.com> (c) 2014-2017\n#           dr-prodigy <maurizio.montel@gmail.com> (c) 2017-2021\n#  Website: https://github.com/dr-prodigy/python-holidays\n#  License: MIT (see LICENSE file)\n\nfrom datetime import timedelta, datetime, date\n\nimport six\nfrom dateutil.parser import parse\n\n\nclass HolidayBase(dict):\n    PROVINCES = []\n\n    def __init__(\n        self, years=[], expand=True, observed=True, prov=None, state=None\n    ):\n        self.observed = observed\n        self.expand = expand\n        if isinstance(years, int):\n            years = [\n                years,\n            ]\n        self.years = set(years)\n        if not getattr(self, \"prov\", False):\n            self.prov = prov\n        self.state = state\n        for year in list(self.years):\n            self._populate(year)\n\n    def __setattr__(self, key, value):\n        if key == \"observed\" and len(self) > 0:\n            dict.__setattr__(self, key, value)\n            if value is True:\n                # Add (Observed) dates\n                years = list(self.years)\n                self.years = set()\n                self.clear()\n                for year in years:\n                    self._populate(year)\n            else:\n                # Remove (Observed) dates\n                for k, v in list(self.items()):\n                    if v.find(\"Observed\") >= 0:\n                        del self[k]\n        else:\n            return dict.__setattr__(self, key, value)\n\n    def __keytransform__(self, key):\n        if isinstance(key, datetime):\n            key = key.date()\n        elif isinstance(key, date):\n            key = key\n        elif isinstance(key, int) or isinstance(key, float):\n            key = datetime.utcfromtimestamp(key).date()\n        elif isinstance(key, six.string_types):\n            try:\n                key = parse(key).date()\n            except (ValueError, OverflowError):\n                raise ValueError(\"Cannot parse date from string '%s'\" % key)\n        else:\n            raise TypeError(\"Cannot convert type '%s' to date.\" % type(key))\n\n        if self.expand and key.year not in self.years:\n            self.years.add(key.year)\n            self._populate(key.year)\n        return key\n\n    def __contains__(self, key):\n        return dict.__contains__(self, self.__keytransform__(key))\n\n    def __getitem__(self, key):\n        if isinstance(key, slice):\n            if not key.start or not key.stop:\n                raise ValueError(\"Both start and stop must be given.\")\n\n            start = self.__keytransform__(key.start)\n            stop = self.__keytransform__(key.stop)\n\n            if key.step is None:\n                step = 1\n            elif isinstance(key.step, timedelta):\n                step = key.step.days\n            elif isinstance(key.step, int):\n                step = key.step\n            else:\n                raise TypeError(\n                    \"Cannot convert type '%s' to int.\" % type(key.step)\n                )\n\n            if step == 0:\n                raise ValueError(\"Step value must not be zero.\")\n\n            date_diff = stop - start\n            if date_diff.days < 0 <= step or date_diff.days >= 0 > step:\n                step *= -1\n\n            days_in_range = []\n            for delta_days in range(0, date_diff.days, step):\n                day = start + timedelta(days=delta_days)\n                try:\n                    dict.__getitem__(self, day)\n                    days_in_range.append(day)\n                except KeyError:\n                    pass\n            return days_in_range\n        return dict.__getitem__(self, self.__keytransform__(key))\n\n    def __setitem__(self, key, value):\n        if key in self:\n            if self.get(key).find(value) < 0 and value.find(self.get(key)) < 0:\n                value = \"%s, %s\" % (value, self.get(key))\n            else:\n                value = self.get(key)\n        return dict.__setitem__(self, self.__keytransform__(key), value)\n\n    def update(self, *args):\n        args = list(args)\n        for arg in args:\n            if isinstance(arg, dict):\n                for key, value in list(arg.items()):\n                    self[key] = value\n            elif isinstance(arg, list):\n                for item in arg:\n                    self[item] = \"Holiday\"\n            else:\n                self[arg] = \"Holiday\"\n\n    def append(self, *args):\n        return self.update(*args)\n\n    def get(self, key, default=None):\n        return dict.get(self, self.__keytransform__(key), default)\n\n    def get_list(self, key):\n        return [h for h in self.get(key, \"\").split(\", \") if h]\n\n    def get_named(self, name):\n        # find all dates matching provided name (accepting partial\n        # strings too, case insensitive), returning them in a list\n        original_expand = self.expand\n        self.expand = False\n        matches = [key for key in self if name.lower() in self[key].lower()]\n        self.expand = original_expand\n        return matches\n\n    def pop(self, key, default=None):\n        if default is None:\n            return dict.pop(self, self.__keytransform__(key))\n        return dict.pop(self, self.__keytransform__(key), default)\n\n    def pop_named(self, name):\n        to_pop = self.get_named(name)\n        if not to_pop:\n            raise KeyError(name)\n        for key in to_pop:\n            self.pop(key)\n        return to_pop\n\n    def __eq__(self, other):\n        return dict.__eq__(self, other) and self.__dict__ == other.__dict__\n\n    def __ne__(self, other):\n        return dict.__ne__(self, other) or self.__dict__ != other.__dict__\n\n    def __add__(self, other):\n        if isinstance(other, int) and other == 0:\n            # Required to sum() list of holidays\n            # sum([h1, h2]) is equivalent to (0 + h1 + h2)\n            return self\n        elif not isinstance(other, HolidayBase):\n            raise TypeError()\n        HolidaySum = createHolidaySum(self, other)\n        country = getattr(self, \"country\", None) or getattr(\n            other, \"country\", None\n        )\n        if self.country and other.country and self.country != other.country:\n            c1 = self.country\n            if not isinstance(c1, list):\n                c1 = [c1]\n            c2 = other.country\n            if not isinstance(c2, list):\n                c2 = [c2]\n            country = c1 + c2\n        prov = getattr(self, \"prov\", None) or getattr(other, \"prov\", None)\n        if self.prov and other.prov and self.prov != other.prov:\n            p1 = self.prov if isinstance(self.prov, list) else [self.prov]\n            p2 = other.prov if isinstance(other.prov, list) else [other.prov]\n            prov = p1 + p2\n        return HolidaySum(\n            years=(self.years | other.years),\n            expand=(self.expand or other.expand),\n            observed=(self.observed or other.observed),\n            country=country,\n            prov=prov,\n        )\n\n    def __radd__(self, other):\n        return self.__add__(other)\n\n    def _populate(self, year):\n        pass\n\n\ndef createHolidaySum(h1, h2):\n    class HolidaySum(HolidayBase):\n        def __init__(self, country, **kwargs):\n            self.country = country\n            self.holidays = []\n            if getattr(h1, \"holidays\", False):\n                for h in h1.holidays:\n                    self.holidays.append(h)\n            else:\n                self.holidays.append(h1)\n            if getattr(h2, \"holidays\", False):\n                for h in h2.holidays:\n                    self.holidays.append(h)\n            else:\n                self.holidays.append(h2)\n            HolidayBase.__init__(self, **kwargs)\n\n        def _populate(self, year):\n            for h in self.holidays[::-1]:\n                h._populate(year)\n                self.update(h)\n\n    return HolidaySum\n", "path": "holidays/holiday_base.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n#  python-holidays\n#  ---------------\n#  A fast, efficient Python library for generating country, province and state\n#  specific sets of holidays on the fly. It aims to make determining whether a\n#  specific date is a holiday as fast and flexible as possible.\n#\n#  Author:  ryanss <ryanssdev@icloud.com> (c) 2014-2017\n#           dr-prodigy <maurizio.montel@gmail.com> (c) 2017-2021\n#  Website: https://github.com/dr-prodigy/python-holidays\n#  License: MIT (see LICENSE file)\n\nfrom datetime import timedelta, datetime, date\n\nimport six\nfrom dateutil.parser import parse\n\n\nclass HolidayBase(dict):\n    PROVINCES = []\n\n    def __init__(\n        self, years=[], expand=True, observed=True, prov=None, state=None\n    ):\n        self.observed = observed\n        self.expand = expand\n        if isinstance(years, int):\n            years = [\n                years,\n            ]\n        self.years = set(years)\n        if not getattr(self, \"prov\", False):\n            self.prov = prov\n        self.state = state\n        for year in list(self.years):\n            self._populate(year)\n\n    def __setattr__(self, key, value):\n        if key == \"observed\" and len(self) > 0:\n            dict.__setattr__(self, key, value)\n            if value is True:\n                # Add (Observed) dates\n                years = list(self.years)\n                self.years = set()\n                self.clear()\n                for year in years:\n                    self._populate(year)\n            else:\n                # Remove (Observed) dates\n                for k, v in list(self.items()):\n                    if v.find(\"Observed\") >= 0:\n                        del self[k]\n        else:\n            return dict.__setattr__(self, key, value)\n\n    def __keytransform__(self, key):\n        if isinstance(key, datetime):\n            key = key.date()\n        elif isinstance(key, date):\n            key = key\n        elif isinstance(key, int) or isinstance(key, float):\n            key = datetime.utcfromtimestamp(key).date()\n        elif isinstance(key, six.string_types):\n            try:\n                key = parse(key).date()\n            except (ValueError, OverflowError):\n                raise ValueError(\"Cannot parse date from string '%s'\" % key)\n        else:\n            raise TypeError(\"Cannot convert type '%s' to date.\" % type(key))\n\n        if self.expand and key.year not in self.years:\n            self.years.add(key.year)\n            self._populate(key.year)\n        return key\n\n    def __contains__(self, key):\n        return dict.__contains__(self, self.__keytransform__(key))\n\n    def __getitem__(self, key):\n        if isinstance(key, slice):\n            if not key.start or not key.stop:\n                raise ValueError(\"Both start and stop must be given.\")\n\n            start = self.__keytransform__(key.start)\n            stop = self.__keytransform__(key.stop)\n\n            if key.step is None:\n                step = 1\n            elif isinstance(key.step, timedelta):\n                step = key.step.days\n            elif isinstance(key.step, int):\n                step = key.step\n            else:\n                raise TypeError(\n                    \"Cannot convert type '%s' to int.\" % type(key.step)\n                )\n\n            if step == 0:\n                raise ValueError(\"Step value must not be zero.\")\n\n            date_diff = stop - start\n            if date_diff.days < 0 <= step or date_diff.days >= 0 > step:\n                step *= -1\n\n            days_in_range = []\n            for delta_days in range(0, date_diff.days, step):\n                day = start + timedelta(days=delta_days)\n                try:\n                    dict.__getitem__(self, day)\n                    days_in_range.append(day)\n                except KeyError:\n                    pass\n            return days_in_range\n        return dict.__getitem__(self, self.__keytransform__(key))\n\n    def __setitem__(self, key, value):\n        if key in self:\n            if self.get(key).find(value) < 0 and value.find(self.get(key)) < 0:\n                value = \"%s, %s\" % (value, self.get(key))\n            else:\n                value = self.get(key)\n        return dict.__setitem__(self, self.__keytransform__(key), value)\n\n    def update(self, *args):\n        args = list(args)\n        for arg in args:\n            if isinstance(arg, dict):\n                for key, value in list(arg.items()):\n                    self[key] = value\n            elif isinstance(arg, list):\n                for item in arg:\n                    self[item] = \"Holiday\"\n            else:\n                self[arg] = \"Holiday\"\n\n    def append(self, *args):\n        return self.update(*args)\n\n    def get(self, key, default=None):\n        return dict.get(self, self.__keytransform__(key), default)\n\n    def get_list(self, key):\n        return [h for h in self.get(key, \"\").split(\", \") if h]\n\n    def get_named(self, name):\n        # find all dates matching provided name (accepting partial\n        # strings too, case insensitive), returning them in a list\n        original_expand = self.expand\n        self.expand = False\n        matches = [key for key in self if name.lower() in self[key].lower()]\n        self.expand = original_expand\n        return matches\n\n    def pop(self, key, default=None):\n        if default is None:\n            return dict.pop(self, self.__keytransform__(key))\n        return dict.pop(self, self.__keytransform__(key), default)\n\n    def pop_named(self, name):\n        to_pop = self.get_named(name)\n        if not to_pop:\n            raise KeyError(name)\n        for key in to_pop:\n            self.pop(key)\n        return to_pop\n\n    def __eq__(self, other):\n        return dict.__eq__(self, other) and self.__dict__ == other.__dict__\n\n    def __ne__(self, other):\n        return dict.__ne__(self, other) or self.__dict__ != other.__dict__\n\n    def __add__(self, other):\n        if isinstance(other, int) and other == 0:\n            # Required to sum() list of holidays\n            # sum([h1, h2]) is equivalent to (0 + h1 + h2)\n            return self\n        elif not isinstance(other, HolidayBase):\n            raise TypeError()\n        HolidaySum = createHolidaySum(self, other)\n        country = getattr(self, \"country\", None) or getattr(\n            other, \"country\", None\n        )\n        if self.country and other.country and self.country != other.country:\n            c1 = self.country\n            if not isinstance(c1, list):\n                c1 = [c1]\n            c2 = other.country\n            if not isinstance(c2, list):\n                c2 = [c2]\n            country = c1 + c2\n        prov = getattr(self, \"prov\", None) or getattr(other, \"prov\", None)\n        if self.prov and other.prov and self.prov != other.prov:\n            p1 = self.prov if isinstance(self.prov, list) else [self.prov]\n            p2 = other.prov if isinstance(other.prov, list) else [other.prov]\n            prov = p1 + p2\n        return HolidaySum(\n            years=(self.years | other.years),\n            expand=(self.expand or other.expand),\n            observed=(self.observed or other.observed),\n            country=country,\n            prov=prov,\n        )\n\n    def __radd__(self, other):\n        return self.__add__(other)\n\n    def _populate(self, year):\n        pass\n\n    def __reduce__(self):\n        return super(HolidayBase, self).__reduce__()\n\n\ndef createHolidaySum(h1, h2):\n    class HolidaySum(HolidayBase):\n        def __init__(self, country, **kwargs):\n            self.country = country\n            self.holidays = []\n            if getattr(h1, \"holidays\", False):\n                for h in h1.holidays:\n                    self.holidays.append(h)\n            else:\n                self.holidays.append(h1)\n            if getattr(h2, \"holidays\", False):\n                for h in h2.holidays:\n                    self.holidays.append(h)\n            else:\n                self.holidays.append(h2)\n            HolidayBase.__init__(self, **kwargs)\n\n        def _populate(self, year):\n            for h in self.holidays[::-1]:\n                h._populate(year)\n                self.update(h)\n\n    return HolidaySum\n", "path": "holidays/holiday_base.py"}]}