We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[feature request] Factory default for extension attributes
## Feature description
As usual with Python, mutable defaults are a big no-no for extension attributes, since they are shared by all instances, which leads to subtle and ~~quick to anger~~ hard to root out bugs (see e.g. #2581).
The documentation mentions that pitfall, but doesn't offer a convenient solution: if I want to keep a static list of interesting spans in my document in a `Doc._.interesting`, it is not clear where the getter and setter that I am supposed to use for this property should store the state. (From what I understand, it should probably be somewhere in `Doc.user_data`, but I have not found a lot of doc on that either)

I propose a `factory` argument to `set_extension` that would be called the first time that the value for the corresponding extension property is retrieved for a given instance (as `collections.defaultdict` does), so one could just write

```python
spacy.tokens.Doc.set_extension('interesting', factory=list)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `spacy/tokens/underscore.py`
Content:
```
1 # coding: utf8
2 from __future__ import unicode_literals
3 
4 import functools
5 
6 from ..errors import Errors
7 
8 
9 class Underscore(object):
10     doc_extensions = {}
11     span_extensions = {}
12     token_extensions = {}
13 
14     def __init__(self, extensions, obj, start=None, end=None):
15         object.__setattr__(self, "_extensions", extensions)
16         object.__setattr__(self, "_obj", obj)
17         # Assumption is that for doc values, _start and _end will both be None
18         # Span will set non-None values for _start and _end
19         # Token will have _start be non-None, _end be None
20         # This lets us key everything into the doc.user_data dictionary,
21         # (see _get_key), and lets us use a single Underscore class.
22         object.__setattr__(self, "_doc", obj.doc)
23         object.__setattr__(self, "_start", start)
24         object.__setattr__(self, "_end", end)
25 
26     def __getattr__(self, name):
27         if name not in self._extensions:
28             raise AttributeError(Errors.E046.format(name=name))
29         default, method, getter, setter = self._extensions[name]
30         if getter is not None:
31             return getter(self._obj)
32         elif method is not None:
33             return functools.partial(method, self._obj)
34         else:
35             return self._doc.user_data.get(self._get_key(name), default)
36 
37     def __setattr__(self, name, value):
38         if name not in self._extensions:
39             raise AttributeError(Errors.E047.format(name=name))
40         default, method, getter, setter = self._extensions[name]
41         if setter is not None:
42             return setter(self._obj, value)
43         else:
44             self._doc.user_data[self._get_key(name)] = value
45 
46     def set(self, name, value):
47         return self.__setattr__(name, value)
48 
49     def get(self, name):
50         return self.__getattr__(name)
51 
52     def has(self, name):
53         return name in self._extensions
54 
55     def _get_key(self, name):
56         return ("._.", name, self._start, self._end)
57 
58 
59 def get_ext_args(**kwargs):
60     """Validate and convert arguments. Reused in Doc, Token and Span."""
61     default = kwargs.get("default")
62     getter = kwargs.get("getter")
63     setter = kwargs.get("setter")
64     method = kwargs.get("method")
65     if getter is None and setter is not None:
66         raise ValueError(Errors.E089)
67     valid_opts = ("default" in kwargs, method is not None, getter is not None)
68     nr_defined = sum(t is True for t in valid_opts)
69     if nr_defined != 1:
70         raise ValueError(Errors.E083.format(nr_defined=nr_defined))
71     if setter is not None and not hasattr(setter, "__call__"):
72         raise ValueError(Errors.E091.format(name="setter", value=repr(setter)))
73     if getter is not None and not hasattr(getter, "__call__"):
74         raise ValueError(Errors.E091.format(name="getter", value=repr(getter)))
75     if method is not None and not hasattr(method, "__call__"):
76         raise ValueError(Errors.E091.format(name="method", value=repr(method)))
77     return (default, method, getter, setter)
78 
79 
80 def is_writable_attr(ext):
81     """Check if an extension attribute is writable.
82     ext (tuple): The (default, getter, setter, method) tuple available  via
83         {Doc,Span,Token}.get_extension.
84     RETURNS (bool): Whether the attribute is writable.
85     """
86     default, method, getter, setter = ext
87     # Extension is writable if it has a setter (getter + setter), if it has a
88     # default value (or, if its default value is none, none of the other values
89     # should be set).
90     if setter is not None or default is not None or all(e is None for e in ext):
91         return True
92     return False
93
```
--- 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/spacy/tokens/underscore.py b/spacy/tokens/underscore.py
--- a/spacy/tokens/underscore.py
+++ b/spacy/tokens/underscore.py
@@ -2,11 +2,13 @@
 from __future__ import unicode_literals
 
 import functools
+import copy
 
 from ..errors import Errors
 
 
 class Underscore(object):
+    mutable_types = (dict, list, set)
     doc_extensions = {}
     span_extensions = {}
     token_extensions = {}
@@ -32,7 +34,15 @@
         elif method is not None:
             return functools.partial(method, self._obj)
         else:
-            return self._doc.user_data.get(self._get_key(name), default)
+            key = self._get_key(name)
+            if key in self._doc.user_data:
+                return self._doc.user_data[key]
+            elif isinstance(default, self.mutable_types):
+                # Handle mutable default arguments (see #2581)
+                new_default = copy.copy(default)
+                self.__setattr__(name, new_default)
+                return new_default
+            return default
 
     def __setattr__(self, name, value):
         if name not in self._extensions:

{"golden_diff": "diff --git a/spacy/tokens/underscore.py b/spacy/tokens/underscore.py\n--- a/spacy/tokens/underscore.py\n+++ b/spacy/tokens/underscore.py\n@@ -2,11 +2,13 @@\n from __future__ import unicode_literals\n \n import functools\n+import copy\n \n from ..errors import Errors\n \n \n class Underscore(object):\n+    mutable_types = (dict, list, set)\n     doc_extensions = {}\n     span_extensions = {}\n     token_extensions = {}\n@@ -32,7 +34,15 @@\n         elif method is not None:\n             return functools.partial(method, self._obj)\n         else:\n-            return self._doc.user_data.get(self._get_key(name), default)\n+            key = self._get_key(name)\n+            if key in self._doc.user_data:\n+                return self._doc.user_data[key]\n+            elif isinstance(default, self.mutable_types):\n+                # Handle mutable default arguments (see #2581)\n+                new_default = copy.copy(default)\n+                self.__setattr__(name, new_default)\n+                return new_default\n+            return default\n \n     def __setattr__(self, name, value):\n         if name not in self._extensions:\n", "issue": "[feature request] Factory default for extension attributes\n## Feature description\r\nAs usual with Python, mutable defaults are a big no-no for extension attributes, since they are shared by all instances, which leads to subtle and ~~quick to anger~~ hard to root out bugs (see e.g. #2581).\r\nThe documentation mentions that pitfall, but doesn't offer a convenient solution: if I want to keep a static list of interesting spans in my document in a `Doc._.interesting`, it is not clear where the getter and setter that I am supposed to use for this property should store the state. (From what I understand, it should probably be somewhere in `Doc.user_data`, but I have not found a lot of doc on that either)\r\n\r\nI propose a `factory` argument to `set_extension` that would be called the first time that the value for the corresponding extension property is retrieved for a given instance (as `collections.defaultdict` does), so one could just write\r\n\r\n```python\r\nspacy.tokens.Doc.set_extension('interesting', factory=list)\r\n```\n", "before_files": [{"content": "# coding: utf8\nfrom __future__ import unicode_literals\n\nimport functools\n\nfrom ..errors import Errors\n\n\nclass Underscore(object):\n    doc_extensions = {}\n    span_extensions = {}\n    token_extensions = {}\n\n    def __init__(self, extensions, obj, start=None, end=None):\n        object.__setattr__(self, \"_extensions\", extensions)\n        object.__setattr__(self, \"_obj\", obj)\n        # Assumption is that for doc values, _start and _end will both be None\n        # Span will set non-None values for _start and _end\n        # Token will have _start be non-None, _end be None\n        # This lets us key everything into the doc.user_data dictionary,\n        # (see _get_key), and lets us use a single Underscore class.\n        object.__setattr__(self, \"_doc\", obj.doc)\n        object.__setattr__(self, \"_start\", start)\n        object.__setattr__(self, \"_end\", end)\n\n    def __getattr__(self, name):\n        if name not in self._extensions:\n            raise AttributeError(Errors.E046.format(name=name))\n        default, method, getter, setter = self._extensions[name]\n        if getter is not None:\n            return getter(self._obj)\n        elif method is not None:\n            return functools.partial(method, self._obj)\n        else:\n            return self._doc.user_data.get(self._get_key(name), default)\n\n    def __setattr__(self, name, value):\n        if name not in self._extensions:\n            raise AttributeError(Errors.E047.format(name=name))\n        default, method, getter, setter = self._extensions[name]\n        if setter is not None:\n            return setter(self._obj, value)\n        else:\n            self._doc.user_data[self._get_key(name)] = value\n\n    def set(self, name, value):\n        return self.__setattr__(name, value)\n\n    def get(self, name):\n        return self.__getattr__(name)\n\n    def has(self, name):\n        return name in self._extensions\n\n    def _get_key(self, name):\n        return (\"._.\", name, self._start, self._end)\n\n\ndef get_ext_args(**kwargs):\n    \"\"\"Validate and convert arguments. Reused in Doc, Token and Span.\"\"\"\n    default = kwargs.get(\"default\")\n    getter = kwargs.get(\"getter\")\n    setter = kwargs.get(\"setter\")\n    method = kwargs.get(\"method\")\n    if getter is None and setter is not None:\n        raise ValueError(Errors.E089)\n    valid_opts = (\"default\" in kwargs, method is not None, getter is not None)\n    nr_defined = sum(t is True for t in valid_opts)\n    if nr_defined != 1:\n        raise ValueError(Errors.E083.format(nr_defined=nr_defined))\n    if setter is not None and not hasattr(setter, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"setter\", value=repr(setter)))\n    if getter is not None and not hasattr(getter, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"getter\", value=repr(getter)))\n    if method is not None and not hasattr(method, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"method\", value=repr(method)))\n    return (default, method, getter, setter)\n\n\ndef is_writable_attr(ext):\n    \"\"\"Check if an extension attribute is writable.\n    ext (tuple): The (default, getter, setter, method) tuple available  via\n        {Doc,Span,Token}.get_extension.\n    RETURNS (bool): Whether the attribute is writable.\n    \"\"\"\n    default, method, getter, setter = ext\n    # Extension is writable if it has a setter (getter + setter), if it has a\n    # default value (or, if its default value is none, none of the other values\n    # should be set).\n    if setter is not None or default is not None or all(e is None for e in ext):\n        return True\n    return False\n", "path": "spacy/tokens/underscore.py"}], "after_files": [{"content": "# coding: utf8\nfrom __future__ import unicode_literals\n\nimport functools\nimport copy\n\nfrom ..errors import Errors\n\n\nclass Underscore(object):\n    mutable_types = (dict, list, set)\n    doc_extensions = {}\n    span_extensions = {}\n    token_extensions = {}\n\n    def __init__(self, extensions, obj, start=None, end=None):\n        object.__setattr__(self, \"_extensions\", extensions)\n        object.__setattr__(self, \"_obj\", obj)\n        # Assumption is that for doc values, _start and _end will both be None\n        # Span will set non-None values for _start and _end\n        # Token will have _start be non-None, _end be None\n        # This lets us key everything into the doc.user_data dictionary,\n        # (see _get_key), and lets us use a single Underscore class.\n        object.__setattr__(self, \"_doc\", obj.doc)\n        object.__setattr__(self, \"_start\", start)\n        object.__setattr__(self, \"_end\", end)\n\n    def __getattr__(self, name):\n        if name not in self._extensions:\n            raise AttributeError(Errors.E046.format(name=name))\n        default, method, getter, setter = self._extensions[name]\n        if getter is not None:\n            return getter(self._obj)\n        elif method is not None:\n            return functools.partial(method, self._obj)\n        else:\n            key = self._get_key(name)\n            if key in self._doc.user_data:\n                return self._doc.user_data[key]\n            elif isinstance(default, self.mutable_types):\n                # Handle mutable default arguments (see #2581)\n                new_default = copy.copy(default)\n                self.__setattr__(name, new_default)\n                return new_default\n            return default\n\n    def __setattr__(self, name, value):\n        if name not in self._extensions:\n            raise AttributeError(Errors.E047.format(name=name))\n        default, method, getter, setter = self._extensions[name]\n        if setter is not None:\n            return setter(self._obj, value)\n        else:\n            self._doc.user_data[self._get_key(name)] = value\n\n    def set(self, name, value):\n        return self.__setattr__(name, value)\n\n    def get(self, name):\n        return self.__getattr__(name)\n\n    def has(self, name):\n        return name in self._extensions\n\n    def _get_key(self, name):\n        return (\"._.\", name, self._start, self._end)\n\n\ndef get_ext_args(**kwargs):\n    \"\"\"Validate and convert arguments. Reused in Doc, Token and Span.\"\"\"\n    default = kwargs.get(\"default\")\n    getter = kwargs.get(\"getter\")\n    setter = kwargs.get(\"setter\")\n    method = kwargs.get(\"method\")\n    if getter is None and setter is not None:\n        raise ValueError(Errors.E089)\n    valid_opts = (\"default\" in kwargs, method is not None, getter is not None)\n    nr_defined = sum(t is True for t in valid_opts)\n    if nr_defined != 1:\n        raise ValueError(Errors.E083.format(nr_defined=nr_defined))\n    if setter is not None and not hasattr(setter, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"setter\", value=repr(setter)))\n    if getter is not None and not hasattr(getter, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"getter\", value=repr(getter)))\n    if method is not None and not hasattr(method, \"__call__\"):\n        raise ValueError(Errors.E091.format(name=\"method\", value=repr(method)))\n    return (default, method, getter, setter)\n\n\ndef is_writable_attr(ext):\n    \"\"\"Check if an extension attribute is writable.\n    ext (tuple): The (default, getter, setter, method) tuple available  via\n        {Doc,Span,Token}.get_extension.\n    RETURNS (bool): Whether the attribute is writable.\n    \"\"\"\n    default, method, getter, setter = ext\n    # Extension is writable if it has a setter (getter + setter), if it has a\n    # default value (or, if its default value is none, none of the other values\n    # should be set).\n    if setter is not None or default is not None or all(e is None for e in ext):\n        return True\n    return False\n", "path": "spacy/tokens/underscore.py"}]}