We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Plugin model upgrade: object has no attribute '_reload'
I've already got a fix for this that I'm about to submit. For reference, here are the steps to reproduce in ipython:
```
~$ ipython                                                                     [venv]
Python 3.7.6 (default, Dec 22 2019, 01:09:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import docker

In [2]: c = docker.DockerClient(base_url='unix://var/run/docker.sock')

In [3]: p = c.plugins.get('loki')

In [4]: list(p.upgrade("grafana/loki-docker-driver:latest"))
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-e5fc26fa0514> in <module>
----> 1 list(p.upgrade("grafana/loki-docker-driver:latest"))

~/venv/lib/python3.7/site-packages/docker/models/plugins.py in upgrade(self, remote)
    120         for d in self.client.api.upgrade_plugin(self.name, remote, privileges):
    121             yield d
--> 122         self._reload()
    123
    124

AttributeError: 'Plugin' object has no attribute '_reload'
```

```
docker==4.3.1
Python 3.7.6
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 16:58:31 2020
 OS/Arch:           darwin/amd64
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docker/models/plugins.py`
Content:
```
1 from .. import errors
2 from .resource import Collection, Model
3 
4 
5 class Plugin(Model):
6     """
7     A plugin on the server.
8     """
9     def __repr__(self):
10         return "<%s: '%s'>" % (self.__class__.__name__, self.name)
11 
12     @property
13     def name(self):
14         """
15         The plugin's name.
16         """
17         return self.attrs.get('Name')
18 
19     @property
20     def enabled(self):
21         """
22         Whether the plugin is enabled.
23         """
24         return self.attrs.get('Enabled')
25 
26     @property
27     def settings(self):
28         """
29         A dictionary representing the plugin's configuration.
30         """
31         return self.attrs.get('Settings')
32 
33     def configure(self, options):
34         """
35             Update the plugin's settings.
36 
37             Args:
38                 options (dict): A key-value mapping of options.
39 
40             Raises:
41                 :py:class:`docker.errors.APIError`
42                     If the server returns an error.
43         """
44         self.client.api.configure_plugin(self.name, options)
45         self.reload()
46 
47     def disable(self):
48         """
49             Disable the plugin.
50 
51             Raises:
52                 :py:class:`docker.errors.APIError`
53                     If the server returns an error.
54         """
55 
56         self.client.api.disable_plugin(self.name)
57         self.reload()
58 
59     def enable(self, timeout=0):
60         """
61             Enable the plugin.
62 
63             Args:
64                 timeout (int): Timeout in seconds. Default: 0
65 
66             Raises:
67                 :py:class:`docker.errors.APIError`
68                     If the server returns an error.
69         """
70         self.client.api.enable_plugin(self.name, timeout)
71         self.reload()
72 
73     def push(self):
74         """
75             Push the plugin to a remote registry.
76 
77             Returns:
78                 A dict iterator streaming the status of the upload.
79 
80             Raises:
81                 :py:class:`docker.errors.APIError`
82                     If the server returns an error.
83         """
84         return self.client.api.push_plugin(self.name)
85 
86     def remove(self, force=False):
87         """
88             Remove the plugin from the server.
89 
90             Args:
91                 force (bool): Remove even if the plugin is enabled.
92                     Default: False
93 
94             Raises:
95                 :py:class:`docker.errors.APIError`
96                     If the server returns an error.
97         """
98         return self.client.api.remove_plugin(self.name, force=force)
99 
100     def upgrade(self, remote=None):
101         """
102             Upgrade the plugin.
103 
104             Args:
105                 remote (string): Remote reference to upgrade to. The
106                     ``:latest`` tag is optional and is the default if omitted.
107                     Default: this plugin's name.
108 
109             Returns:
110                 A generator streaming the decoded API logs
111         """
112         if self.enabled:
113             raise errors.DockerError(
114                 'Plugin must be disabled before upgrading.'
115             )
116 
117         if remote is None:
118             remote = self.name
119         privileges = self.client.api.plugin_privileges(remote)
120         for d in self.client.api.upgrade_plugin(self.name, remote, privileges):
121             yield d
122         self._reload()
123 
124 
125 class PluginCollection(Collection):
126     model = Plugin
127 
128     def create(self, name, plugin_data_dir, gzip=False):
129         """
130             Create a new plugin.
131 
132             Args:
133                 name (string): The name of the plugin. The ``:latest`` tag is
134                     optional, and is the default if omitted.
135                 plugin_data_dir (string): Path to the plugin data directory.
136                     Plugin data directory must contain the ``config.json``
137                     manifest file and the ``rootfs`` directory.
138                 gzip (bool): Compress the context using gzip. Default: False
139 
140             Returns:
141                 (:py:class:`Plugin`): The newly created plugin.
142         """
143         self.client.api.create_plugin(name, plugin_data_dir, gzip)
144         return self.get(name)
145 
146     def get(self, name):
147         """
148         Gets a plugin.
149 
150         Args:
151             name (str): The name of the plugin.
152 
153         Returns:
154             (:py:class:`Plugin`): The plugin.
155 
156         Raises:
157             :py:class:`docker.errors.NotFound` If the plugin does not
158             exist.
159             :py:class:`docker.errors.APIError`
160                 If the server returns an error.
161         """
162         return self.prepare_model(self.client.api.inspect_plugin(name))
163 
164     def install(self, remote_name, local_name=None):
165         """
166             Pull and install a plugin.
167 
168             Args:
169                 remote_name (string): Remote reference for the plugin to
170                     install. The ``:latest`` tag is optional, and is the
171                     default if omitted.
172                 local_name (string): Local name for the pulled plugin.
173                     The ``:latest`` tag is optional, and is the default if
174                     omitted. Optional.
175 
176             Returns:
177                 (:py:class:`Plugin`): The installed plugin
178             Raises:
179                 :py:class:`docker.errors.APIError`
180                     If the server returns an error.
181         """
182         privileges = self.client.api.plugin_privileges(remote_name)
183         it = self.client.api.pull_plugin(remote_name, privileges, local_name)
184         for data in it:
185             pass
186         return self.get(local_name or remote_name)
187 
188     def list(self):
189         """
190         List plugins installed on the server.
191 
192         Returns:
193             (list of :py:class:`Plugin`): The plugins.
194 
195         Raises:
196             :py:class:`docker.errors.APIError`
197                 If the server returns an error.
198         """
199         resp = self.client.api.plugins()
200         return [self.prepare_model(r) for r in resp]
201
```
--- 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/docker/models/plugins.py b/docker/models/plugins.py
--- a/docker/models/plugins.py
+++ b/docker/models/plugins.py
@@ -119,7 +119,7 @@
         privileges = self.client.api.plugin_privileges(remote)
         for d in self.client.api.upgrade_plugin(self.name, remote, privileges):
             yield d
-        self._reload()
+        self.reload()
 
 
 class PluginCollection(Collection):

{"golden_diff": "diff --git a/docker/models/plugins.py b/docker/models/plugins.py\n--- a/docker/models/plugins.py\n+++ b/docker/models/plugins.py\n@@ -119,7 +119,7 @@\n         privileges = self.client.api.plugin_privileges(remote)\n         for d in self.client.api.upgrade_plugin(self.name, remote, privileges):\n             yield d\n-        self._reload()\n+        self.reload()\n \n \n class PluginCollection(Collection):\n", "issue": "Plugin model upgrade: object has no attribute '_reload'\nI've already got a fix for this that I'm about to submit. For reference, here are the steps to reproduce in ipython:\r\n```\r\n~$ ipython                                                                     [venv]\r\nPython 3.7.6 (default, Dec 22 2019, 01:09:06)\r\nType 'copyright', 'credits' or 'license' for more information\r\nIPython 7.18.1 -- An enhanced Interactive Python. Type '?' for help.\r\n\r\nIn [1]: import docker\r\n\r\nIn [2]: c = docker.DockerClient(base_url='unix://var/run/docker.sock')\r\n\r\nIn [3]: p = c.plugins.get('loki')\r\n\r\nIn [4]: list(p.upgrade(\"grafana/loki-docker-driver:latest\"))\r\n---------------------------------------------------------------------------\r\nAttributeError                            Traceback (most recent call last)\r\n<ipython-input-4-e5fc26fa0514> in <module>\r\n----> 1 list(p.upgrade(\"grafana/loki-docker-driver:latest\"))\r\n\r\n~/venv/lib/python3.7/site-packages/docker/models/plugins.py in upgrade(self, remote)\r\n    120         for d in self.client.api.upgrade_plugin(self.name, remote, privileges):\r\n    121             yield d\r\n--> 122         self._reload()\r\n    123\r\n    124\r\n\r\nAttributeError: 'Plugin' object has no attribute '_reload'\r\n```\r\n\r\n```\r\ndocker==4.3.1\r\nPython 3.7.6\r\nClient: Docker Engine - Community\r\n Cloud integration  0.1.18\r\n Version:           19.03.13\r\n API version:       1.40\r\n Go version:        go1.13.15\r\n Git commit:        4484c46d9d\r\n Built:             Wed Sep 16 16:58:31 2020\r\n OS/Arch:           darwin/amd64\r\n Experimental:      true\r\n\r\nServer: Docker Engine - Community\r\n Engine:\r\n  Version:          19.03.13\r\n  API version:      1.40 (minimum version 1.12)\r\n  Go version:       go1.13.15\r\n  Git commit:       4484c46d9d\r\n  Built:            Wed Sep 16 17:07:04 2020\r\n  OS/Arch:          linux/amd64\r\n  Experimental:     true\r\n containerd:\r\n  Version:          v1.3.7\r\n  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175\r\n runc:\r\n  Version:          1.0.0-rc10\r\n  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd\r\n docker-init:\r\n  Version:          0.18.0\r\n  GitCommit:        fec3683\r\n```\n", "before_files": [{"content": "from .. import errors\nfrom .resource import Collection, Model\n\n\nclass Plugin(Model):\n    \"\"\"\n    A plugin on the server.\n    \"\"\"\n    def __repr__(self):\n        return \"<%s: '%s'>\" % (self.__class__.__name__, self.name)\n\n    @property\n    def name(self):\n        \"\"\"\n        The plugin's name.\n        \"\"\"\n        return self.attrs.get('Name')\n\n    @property\n    def enabled(self):\n        \"\"\"\n        Whether the plugin is enabled.\n        \"\"\"\n        return self.attrs.get('Enabled')\n\n    @property\n    def settings(self):\n        \"\"\"\n        A dictionary representing the plugin's configuration.\n        \"\"\"\n        return self.attrs.get('Settings')\n\n    def configure(self, options):\n        \"\"\"\n            Update the plugin's settings.\n\n            Args:\n                options (dict): A key-value mapping of options.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        self.client.api.configure_plugin(self.name, options)\n        self.reload()\n\n    def disable(self):\n        \"\"\"\n            Disable the plugin.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n\n        self.client.api.disable_plugin(self.name)\n        self.reload()\n\n    def enable(self, timeout=0):\n        \"\"\"\n            Enable the plugin.\n\n            Args:\n                timeout (int): Timeout in seconds. Default: 0\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        self.client.api.enable_plugin(self.name, timeout)\n        self.reload()\n\n    def push(self):\n        \"\"\"\n            Push the plugin to a remote registry.\n\n            Returns:\n                A dict iterator streaming the status of the upload.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        return self.client.api.push_plugin(self.name)\n\n    def remove(self, force=False):\n        \"\"\"\n            Remove the plugin from the server.\n\n            Args:\n                force (bool): Remove even if the plugin is enabled.\n                    Default: False\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        return self.client.api.remove_plugin(self.name, force=force)\n\n    def upgrade(self, remote=None):\n        \"\"\"\n            Upgrade the plugin.\n\n            Args:\n                remote (string): Remote reference to upgrade to. The\n                    ``:latest`` tag is optional and is the default if omitted.\n                    Default: this plugin's name.\n\n            Returns:\n                A generator streaming the decoded API logs\n        \"\"\"\n        if self.enabled:\n            raise errors.DockerError(\n                'Plugin must be disabled before upgrading.'\n            )\n\n        if remote is None:\n            remote = self.name\n        privileges = self.client.api.plugin_privileges(remote)\n        for d in self.client.api.upgrade_plugin(self.name, remote, privileges):\n            yield d\n        self._reload()\n\n\nclass PluginCollection(Collection):\n    model = Plugin\n\n    def create(self, name, plugin_data_dir, gzip=False):\n        \"\"\"\n            Create a new plugin.\n\n            Args:\n                name (string): The name of the plugin. The ``:latest`` tag is\n                    optional, and is the default if omitted.\n                plugin_data_dir (string): Path to the plugin data directory.\n                    Plugin data directory must contain the ``config.json``\n                    manifest file and the ``rootfs`` directory.\n                gzip (bool): Compress the context using gzip. Default: False\n\n            Returns:\n                (:py:class:`Plugin`): The newly created plugin.\n        \"\"\"\n        self.client.api.create_plugin(name, plugin_data_dir, gzip)\n        return self.get(name)\n\n    def get(self, name):\n        \"\"\"\n        Gets a plugin.\n\n        Args:\n            name (str): The name of the plugin.\n\n        Returns:\n            (:py:class:`Plugin`): The plugin.\n\n        Raises:\n            :py:class:`docker.errors.NotFound` If the plugin does not\n            exist.\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.prepare_model(self.client.api.inspect_plugin(name))\n\n    def install(self, remote_name, local_name=None):\n        \"\"\"\n            Pull and install a plugin.\n\n            Args:\n                remote_name (string): Remote reference for the plugin to\n                    install. The ``:latest`` tag is optional, and is the\n                    default if omitted.\n                local_name (string): Local name for the pulled plugin.\n                    The ``:latest`` tag is optional, and is the default if\n                    omitted. Optional.\n\n            Returns:\n                (:py:class:`Plugin`): The installed plugin\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        privileges = self.client.api.plugin_privileges(remote_name)\n        it = self.client.api.pull_plugin(remote_name, privileges, local_name)\n        for data in it:\n            pass\n        return self.get(local_name or remote_name)\n\n    def list(self):\n        \"\"\"\n        List plugins installed on the server.\n\n        Returns:\n            (list of :py:class:`Plugin`): The plugins.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        resp = self.client.api.plugins()\n        return [self.prepare_model(r) for r in resp]\n", "path": "docker/models/plugins.py"}], "after_files": [{"content": "from .. import errors\nfrom .resource import Collection, Model\n\n\nclass Plugin(Model):\n    \"\"\"\n    A plugin on the server.\n    \"\"\"\n    def __repr__(self):\n        return \"<%s: '%s'>\" % (self.__class__.__name__, self.name)\n\n    @property\n    def name(self):\n        \"\"\"\n        The plugin's name.\n        \"\"\"\n        return self.attrs.get('Name')\n\n    @property\n    def enabled(self):\n        \"\"\"\n        Whether the plugin is enabled.\n        \"\"\"\n        return self.attrs.get('Enabled')\n\n    @property\n    def settings(self):\n        \"\"\"\n        A dictionary representing the plugin's configuration.\n        \"\"\"\n        return self.attrs.get('Settings')\n\n    def configure(self, options):\n        \"\"\"\n            Update the plugin's settings.\n\n            Args:\n                options (dict): A key-value mapping of options.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        self.client.api.configure_plugin(self.name, options)\n        self.reload()\n\n    def disable(self):\n        \"\"\"\n            Disable the plugin.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n\n        self.client.api.disable_plugin(self.name)\n        self.reload()\n\n    def enable(self, timeout=0):\n        \"\"\"\n            Enable the plugin.\n\n            Args:\n                timeout (int): Timeout in seconds. Default: 0\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        self.client.api.enable_plugin(self.name, timeout)\n        self.reload()\n\n    def push(self):\n        \"\"\"\n            Push the plugin to a remote registry.\n\n            Returns:\n                A dict iterator streaming the status of the upload.\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        return self.client.api.push_plugin(self.name)\n\n    def remove(self, force=False):\n        \"\"\"\n            Remove the plugin from the server.\n\n            Args:\n                force (bool): Remove even if the plugin is enabled.\n                    Default: False\n\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        return self.client.api.remove_plugin(self.name, force=force)\n\n    def upgrade(self, remote=None):\n        \"\"\"\n            Upgrade the plugin.\n\n            Args:\n                remote (string): Remote reference to upgrade to. The\n                    ``:latest`` tag is optional and is the default if omitted.\n                    Default: this plugin's name.\n\n            Returns:\n                A generator streaming the decoded API logs\n        \"\"\"\n        if self.enabled:\n            raise errors.DockerError(\n                'Plugin must be disabled before upgrading.'\n            )\n\n        if remote is None:\n            remote = self.name\n        privileges = self.client.api.plugin_privileges(remote)\n        for d in self.client.api.upgrade_plugin(self.name, remote, privileges):\n            yield d\n        self.reload()\n\n\nclass PluginCollection(Collection):\n    model = Plugin\n\n    def create(self, name, plugin_data_dir, gzip=False):\n        \"\"\"\n            Create a new plugin.\n\n            Args:\n                name (string): The name of the plugin. The ``:latest`` tag is\n                    optional, and is the default if omitted.\n                plugin_data_dir (string): Path to the plugin data directory.\n                    Plugin data directory must contain the ``config.json``\n                    manifest file and the ``rootfs`` directory.\n                gzip (bool): Compress the context using gzip. Default: False\n\n            Returns:\n                (:py:class:`Plugin`): The newly created plugin.\n        \"\"\"\n        self.client.api.create_plugin(name, plugin_data_dir, gzip)\n        return self.get(name)\n\n    def get(self, name):\n        \"\"\"\n        Gets a plugin.\n\n        Args:\n            name (str): The name of the plugin.\n\n        Returns:\n            (:py:class:`Plugin`): The plugin.\n\n        Raises:\n            :py:class:`docker.errors.NotFound` If the plugin does not\n            exist.\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.prepare_model(self.client.api.inspect_plugin(name))\n\n    def install(self, remote_name, local_name=None):\n        \"\"\"\n            Pull and install a plugin.\n\n            Args:\n                remote_name (string): Remote reference for the plugin to\n                    install. The ``:latest`` tag is optional, and is the\n                    default if omitted.\n                local_name (string): Local name for the pulled plugin.\n                    The ``:latest`` tag is optional, and is the default if\n                    omitted. Optional.\n\n            Returns:\n                (:py:class:`Plugin`): The installed plugin\n            Raises:\n                :py:class:`docker.errors.APIError`\n                    If the server returns an error.\n        \"\"\"\n        privileges = self.client.api.plugin_privileges(remote_name)\n        it = self.client.api.pull_plugin(remote_name, privileges, local_name)\n        for data in it:\n            pass\n        return self.get(local_name or remote_name)\n\n    def list(self):\n        \"\"\"\n        List plugins installed on the server.\n\n        Returns:\n            (list of :py:class:`Plugin`): The plugins.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        resp = self.client.api.plugins()\n        return [self.prepare_model(r) for r in resp]\n", "path": "docker/models/plugins.py"}]}