prompt: 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()
  
  ```
  
golden_diff: 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:
  
verification_info: {"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"}]}