We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
distutils depreaction
https://www.python.org/dev/peps/pep-0632/

We have one module using this: `avocado.utils.kernel`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `avocado/utils/kernel.py`
Content:
```
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
5 #
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 #
10 # See LICENSE for more details.
11 #
12 # Copyright: Red Hat Inc. 2014
13 # Author: Ruda Moura <rmoura@redhat.com>
14 # Author: Santhosh G <santhog4@linux.vnet.ibm.com>
15 
16 """
17 Provides utilities for the Linux kernel.
18 """
19 
20 import logging
21 import multiprocessing
22 import os
23 import shutil
24 import tempfile
25 from distutils.version import LooseVersion  # pylint: disable=E0611
26 
27 from . import archive, asset, build, distro, process
28 
29 LOG = logging.getLogger('avocado.test')
30 
31 
32 class KernelBuild:
33 
34     """
35     Build the Linux Kernel from official tarballs.
36     """
37 
38     URL = 'https://www.kernel.org/pub/linux/kernel/v{major}.x/'
39     SOURCE = 'linux-{version}.tar.gz'
40 
41     def __init__(self, version, config_path=None, work_dir=None,
42                  data_dirs=None):
43         """
44         Creates an instance of :class:`KernelBuild`.
45 
46         :param version: kernel version ("3.19.8").
47         :param config_path: path to config file.
48         :param work_dir: work directory.
49         :param data_dirs: list of directories to keep the downloaded kernel
50         :return: None.
51         """
52         self.asset_path = None
53         self.version = version
54         self.config_path = config_path
55         self.distro = distro.detect()
56         if work_dir is None:
57             work_dir = tempfile.mkdtemp(prefix='avocado_' + __name__)
58         self.work_dir = work_dir
59         if data_dirs is not None:
60             self.data_dirs = data_dirs
61         else:
62             self.data_dirs = [self.work_dir]
63         self._build_dir = os.path.join(self.work_dir, 'linux-%s' % self.version)
64 
65     def __repr__(self):
66         return "KernelBuild('%s, %s, %s')" % (self.version,
67                                               self.config_path,
68                                               self.work_dir)
69 
70     @property
71     def vmlinux(self):
72         """
73         Return the vmlinux path if the file exists
74         """
75         if not self.build_dir:
76             return None
77         vmlinux_path = os.path.join(self.build_dir, 'vmlinux')
78         if os.path.isfile(vmlinux_path):
79             return vmlinux_path
80         return None
81 
82     @property
83     def build_dir(self):
84         """
85         Return the build path if the directory exists
86         """
87         if os.path.isdir(self._build_dir):
88             return self._build_dir
89         return None
90 
91     def _build_kernel_url(self, base_url=None):
92         kernel_file = self.SOURCE.format(version=self.version)
93         if base_url is None:
94             base_url = self.URL.format(major=self.version.split('.', 1)[0])
95         return base_url + kernel_file
96 
97     def download(self, url=None):
98         """
99         Download kernel source.
100 
101         :param url: override the url from where to fetch the kernel
102                     source tarball
103         :type url: str or None
104         """
105         full_url = self._build_kernel_url(base_url=url)
106         self.asset_path = asset.Asset(full_url, asset_hash=None,
107                                       algorithm=None, locations=None,
108                                       cache_dirs=self.data_dirs).fetch()
109 
110     def uncompress(self):
111         """
112         Uncompress kernel source.
113 
114         :raises: Exception in case the tarball is not downloaded
115         """
116         if self.asset_path:
117             LOG.info("Uncompressing tarball")
118             archive.extract(self.asset_path, self.work_dir)
119         else:
120             raise Exception("Unable to find the tarball")
121 
122     def configure(self, targets=('defconfig'), extra_configs=None):
123         """
124         Configure/prepare kernel source to build.
125 
126         :param targets: configuration targets. Default is 'defconfig'.
127         :type targets: list of str
128         :param extra_configs: additional configurations in the form of
129                               CONFIG_NAME=VALUE.
130         :type extra_configs: list of str
131         """
132         build.make(self._build_dir, extra_args='-C %s mrproper' %
133                    self._build_dir)
134         if self.config_path is not None:
135             dotconfig = os.path.join(self._build_dir, '.config')
136             shutil.copy(self.config_path, dotconfig)
137             build.make(self._build_dir, extra_args='-C %s olddefconfig' %
138                        self._build_dir)
139         else:
140             if isinstance(targets, list):
141                 _targets = " ".join(targets)
142             else:
143                 _targets = targets
144             build.make(self.build_dir,
145                        extra_args='-C %s %s' % (self.build_dir, _targets))
146         if extra_configs:
147             with tempfile.NamedTemporaryFile(mode='w+t',
148                                              prefix='avocado_') as config_file:
149                 config_file.write('\n'.join(extra_configs))
150                 config_file.flush()
151                 cmd = ['cd', self._build_dir, '&&',
152                        './scripts/kconfig/merge_config.sh', '.config',
153                        config_file.name]
154                 process.run(" ".join(cmd), shell=True)
155 
156     def build(self, binary_package=False, njobs=multiprocessing.cpu_count()):
157         """
158         Build kernel from source.
159 
160         :param binary_package: when True, the appropriate
161                                   platform package is built
162                                   for install() to use
163         :type binary_pacakge: bool
164         :param njobs: number of jobs. It is mapped to the -j option from make.
165                       If njobs is None then do not limit the number of jobs
166                       (e.g. uses -j without value). The -j is omitted if a
167                       value equal or less than zero is passed. Default value
168                       is set to `multiprocessing.cpu_count()`.
169         :type njobs: int or None
170         """
171         make_args = []
172         LOG.info("Starting build the kernel")
173 
174         if njobs is None:
175             make_args.append('-j')
176         elif njobs > 0:
177             make_args.extend(['-j', str(njobs)])
178         make_args.extend(['-C', self._build_dir])
179 
180         if binary_package is True:
181             if self.distro.name == "Ubuntu":
182                 make_args.append("deb-pkg")
183 
184         build.make(self._build_dir, extra_args=" ".join(make_args))
185 
186     def install(self):
187         """
188         Install built kernel.
189         """
190         LOG.info("Starting kernel install")
191         if self.distro.name == "Ubuntu":
192             process.run('dpkg -i %s/*.deb' %
193                         self.work_dir, shell=True, sudo=True)
194         else:
195             LOG.info("Skipping kernel install")
196 
197     def __del__(self):
198         shutil.rmtree(self.work_dir)
199 
200 
201 def check_version(version):
202     """
203     This utility function compares the current kernel version with
204     the version parameter and gives assertion error if the version
205     parameter is greater.
206 
207     :type version: string
208     :param version: version to be compared with current kernel version
209     """
210     assert LooseVersion(os.uname()[2]) > LooseVersion(version), "Old kernel"
211
```
--- 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/avocado/utils/kernel.py b/avocado/utils/kernel.py
--- a/avocado/utils/kernel.py
+++ b/avocado/utils/kernel.py
@@ -22,7 +22,8 @@
 import os
 import shutil
 import tempfile
-from distutils.version import LooseVersion  # pylint: disable=E0611
+
+from pkg_resources import packaging
 
 from . import archive, asset, build, distro, process
 
@@ -207,4 +208,6 @@
     :type version: string
     :param version: version to be compared with current kernel version
     """
-    assert LooseVersion(os.uname()[2]) > LooseVersion(version), "Old kernel"
+    os_version = packaging.version.parse(os.uname()[2])
+    version = packaging.version.parse(version)
+    assert os_version > version, "Old kernel"
\ No newline at end of file

{"golden_diff": "diff --git a/avocado/utils/kernel.py b/avocado/utils/kernel.py\n--- a/avocado/utils/kernel.py\n+++ b/avocado/utils/kernel.py\n@@ -22,7 +22,8 @@\n import os\n import shutil\n import tempfile\n-from distutils.version import LooseVersion  # pylint: disable=E0611\n+\n+from pkg_resources import packaging\n \n from . import archive, asset, build, distro, process\n \n@@ -207,4 +208,6 @@\n     :type version: string\n     :param version: version to be compared with current kernel version\n     \"\"\"\n-    assert LooseVersion(os.uname()[2]) > LooseVersion(version), \"Old kernel\"\n+    os_version = packaging.version.parse(os.uname()[2])\n+    version = packaging.version.parse(version)\n+    assert os_version > version, \"Old kernel\"\n\\ No newline at end of file\n", "issue": "distutils depreaction\nhttps://www.python.org/dev/peps/pep-0632/\r\n\r\nWe have one module using this: `avocado.utils.kernel`.\n", "before_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2014\n# Author: Ruda Moura <rmoura@redhat.com>\n# Author: Santhosh G <santhog4@linux.vnet.ibm.com>\n\n\"\"\"\nProvides utilities for the Linux kernel.\n\"\"\"\n\nimport logging\nimport multiprocessing\nimport os\nimport shutil\nimport tempfile\nfrom distutils.version import LooseVersion  # pylint: disable=E0611\n\nfrom . import archive, asset, build, distro, process\n\nLOG = logging.getLogger('avocado.test')\n\n\nclass KernelBuild:\n\n    \"\"\"\n    Build the Linux Kernel from official tarballs.\n    \"\"\"\n\n    URL = 'https://www.kernel.org/pub/linux/kernel/v{major}.x/'\n    SOURCE = 'linux-{version}.tar.gz'\n\n    def __init__(self, version, config_path=None, work_dir=None,\n                 data_dirs=None):\n        \"\"\"\n        Creates an instance of :class:`KernelBuild`.\n\n        :param version: kernel version (\"3.19.8\").\n        :param config_path: path to config file.\n        :param work_dir: work directory.\n        :param data_dirs: list of directories to keep the downloaded kernel\n        :return: None.\n        \"\"\"\n        self.asset_path = None\n        self.version = version\n        self.config_path = config_path\n        self.distro = distro.detect()\n        if work_dir is None:\n            work_dir = tempfile.mkdtemp(prefix='avocado_' + __name__)\n        self.work_dir = work_dir\n        if data_dirs is not None:\n            self.data_dirs = data_dirs\n        else:\n            self.data_dirs = [self.work_dir]\n        self._build_dir = os.path.join(self.work_dir, 'linux-%s' % self.version)\n\n    def __repr__(self):\n        return \"KernelBuild('%s, %s, %s')\" % (self.version,\n                                              self.config_path,\n                                              self.work_dir)\n\n    @property\n    def vmlinux(self):\n        \"\"\"\n        Return the vmlinux path if the file exists\n        \"\"\"\n        if not self.build_dir:\n            return None\n        vmlinux_path = os.path.join(self.build_dir, 'vmlinux')\n        if os.path.isfile(vmlinux_path):\n            return vmlinux_path\n        return None\n\n    @property\n    def build_dir(self):\n        \"\"\"\n        Return the build path if the directory exists\n        \"\"\"\n        if os.path.isdir(self._build_dir):\n            return self._build_dir\n        return None\n\n    def _build_kernel_url(self, base_url=None):\n        kernel_file = self.SOURCE.format(version=self.version)\n        if base_url is None:\n            base_url = self.URL.format(major=self.version.split('.', 1)[0])\n        return base_url + kernel_file\n\n    def download(self, url=None):\n        \"\"\"\n        Download kernel source.\n\n        :param url: override the url from where to fetch the kernel\n                    source tarball\n        :type url: str or None\n        \"\"\"\n        full_url = self._build_kernel_url(base_url=url)\n        self.asset_path = asset.Asset(full_url, asset_hash=None,\n                                      algorithm=None, locations=None,\n                                      cache_dirs=self.data_dirs).fetch()\n\n    def uncompress(self):\n        \"\"\"\n        Uncompress kernel source.\n\n        :raises: Exception in case the tarball is not downloaded\n        \"\"\"\n        if self.asset_path:\n            LOG.info(\"Uncompressing tarball\")\n            archive.extract(self.asset_path, self.work_dir)\n        else:\n            raise Exception(\"Unable to find the tarball\")\n\n    def configure(self, targets=('defconfig'), extra_configs=None):\n        \"\"\"\n        Configure/prepare kernel source to build.\n\n        :param targets: configuration targets. Default is 'defconfig'.\n        :type targets: list of str\n        :param extra_configs: additional configurations in the form of\n                              CONFIG_NAME=VALUE.\n        :type extra_configs: list of str\n        \"\"\"\n        build.make(self._build_dir, extra_args='-C %s mrproper' %\n                   self._build_dir)\n        if self.config_path is not None:\n            dotconfig = os.path.join(self._build_dir, '.config')\n            shutil.copy(self.config_path, dotconfig)\n            build.make(self._build_dir, extra_args='-C %s olddefconfig' %\n                       self._build_dir)\n        else:\n            if isinstance(targets, list):\n                _targets = \" \".join(targets)\n            else:\n                _targets = targets\n            build.make(self.build_dir,\n                       extra_args='-C %s %s' % (self.build_dir, _targets))\n        if extra_configs:\n            with tempfile.NamedTemporaryFile(mode='w+t',\n                                             prefix='avocado_') as config_file:\n                config_file.write('\\n'.join(extra_configs))\n                config_file.flush()\n                cmd = ['cd', self._build_dir, '&&',\n                       './scripts/kconfig/merge_config.sh', '.config',\n                       config_file.name]\n                process.run(\" \".join(cmd), shell=True)\n\n    def build(self, binary_package=False, njobs=multiprocessing.cpu_count()):\n        \"\"\"\n        Build kernel from source.\n\n        :param binary_package: when True, the appropriate\n                                  platform package is built\n                                  for install() to use\n        :type binary_pacakge: bool\n        :param njobs: number of jobs. It is mapped to the -j option from make.\n                      If njobs is None then do not limit the number of jobs\n                      (e.g. uses -j without value). The -j is omitted if a\n                      value equal or less than zero is passed. Default value\n                      is set to `multiprocessing.cpu_count()`.\n        :type njobs: int or None\n        \"\"\"\n        make_args = []\n        LOG.info(\"Starting build the kernel\")\n\n        if njobs is None:\n            make_args.append('-j')\n        elif njobs > 0:\n            make_args.extend(['-j', str(njobs)])\n        make_args.extend(['-C', self._build_dir])\n\n        if binary_package is True:\n            if self.distro.name == \"Ubuntu\":\n                make_args.append(\"deb-pkg\")\n\n        build.make(self._build_dir, extra_args=\" \".join(make_args))\n\n    def install(self):\n        \"\"\"\n        Install built kernel.\n        \"\"\"\n        LOG.info(\"Starting kernel install\")\n        if self.distro.name == \"Ubuntu\":\n            process.run('dpkg -i %s/*.deb' %\n                        self.work_dir, shell=True, sudo=True)\n        else:\n            LOG.info(\"Skipping kernel install\")\n\n    def __del__(self):\n        shutil.rmtree(self.work_dir)\n\n\ndef check_version(version):\n    \"\"\"\n    This utility function compares the current kernel version with\n    the version parameter and gives assertion error if the version\n    parameter is greater.\n\n    :type version: string\n    :param version: version to be compared with current kernel version\n    \"\"\"\n    assert LooseVersion(os.uname()[2]) > LooseVersion(version), \"Old kernel\"\n", "path": "avocado/utils/kernel.py"}], "after_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2014\n# Author: Ruda Moura <rmoura@redhat.com>\n# Author: Santhosh G <santhog4@linux.vnet.ibm.com>\n\n\"\"\"\nProvides utilities for the Linux kernel.\n\"\"\"\n\nimport logging\nimport multiprocessing\nimport os\nimport shutil\nimport tempfile\n\nfrom pkg_resources import packaging\n\nfrom . import archive, asset, build, distro, process\n\nLOG = logging.getLogger('avocado.test')\n\n\nclass KernelBuild:\n\n    \"\"\"\n    Build the Linux Kernel from official tarballs.\n    \"\"\"\n\n    URL = 'https://www.kernel.org/pub/linux/kernel/v{major}.x/'\n    SOURCE = 'linux-{version}.tar.gz'\n\n    def __init__(self, version, config_path=None, work_dir=None,\n                 data_dirs=None):\n        \"\"\"\n        Creates an instance of :class:`KernelBuild`.\n\n        :param version: kernel version (\"3.19.8\").\n        :param config_path: path to config file.\n        :param work_dir: work directory.\n        :param data_dirs: list of directories to keep the downloaded kernel\n        :return: None.\n        \"\"\"\n        self.asset_path = None\n        self.version = version\n        self.config_path = config_path\n        self.distro = distro.detect()\n        if work_dir is None:\n            work_dir = tempfile.mkdtemp(prefix='avocado_' + __name__)\n        self.work_dir = work_dir\n        if data_dirs is not None:\n            self.data_dirs = data_dirs\n        else:\n            self.data_dirs = [self.work_dir]\n        self._build_dir = os.path.join(self.work_dir, 'linux-%s' % self.version)\n\n    def __repr__(self):\n        return \"KernelBuild('%s, %s, %s')\" % (self.version,\n                                              self.config_path,\n                                              self.work_dir)\n\n    @property\n    def vmlinux(self):\n        \"\"\"\n        Return the vmlinux path if the file exists\n        \"\"\"\n        if not self.build_dir:\n            return None\n        vmlinux_path = os.path.join(self.build_dir, 'vmlinux')\n        if os.path.isfile(vmlinux_path):\n            return vmlinux_path\n        return None\n\n    @property\n    def build_dir(self):\n        \"\"\"\n        Return the build path if the directory exists\n        \"\"\"\n        if os.path.isdir(self._build_dir):\n            return self._build_dir\n        return None\n\n    def _build_kernel_url(self, base_url=None):\n        kernel_file = self.SOURCE.format(version=self.version)\n        if base_url is None:\n            base_url = self.URL.format(major=self.version.split('.', 1)[0])\n        return base_url + kernel_file\n\n    def download(self, url=None):\n        \"\"\"\n        Download kernel source.\n\n        :param url: override the url from where to fetch the kernel\n                    source tarball\n        :type url: str or None\n        \"\"\"\n        full_url = self._build_kernel_url(base_url=url)\n        self.asset_path = asset.Asset(full_url, asset_hash=None,\n                                      algorithm=None, locations=None,\n                                      cache_dirs=self.data_dirs).fetch()\n\n    def uncompress(self):\n        \"\"\"\n        Uncompress kernel source.\n\n        :raises: Exception in case the tarball is not downloaded\n        \"\"\"\n        if self.asset_path:\n            LOG.info(\"Uncompressing tarball\")\n            archive.extract(self.asset_path, self.work_dir)\n        else:\n            raise Exception(\"Unable to find the tarball\")\n\n    def configure(self, targets=('defconfig'), extra_configs=None):\n        \"\"\"\n        Configure/prepare kernel source to build.\n\n        :param targets: configuration targets. Default is 'defconfig'.\n        :type targets: list of str\n        :param extra_configs: additional configurations in the form of\n                              CONFIG_NAME=VALUE.\n        :type extra_configs: list of str\n        \"\"\"\n        build.make(self._build_dir, extra_args='-C %s mrproper' %\n                   self._build_dir)\n        if self.config_path is not None:\n            dotconfig = os.path.join(self._build_dir, '.config')\n            shutil.copy(self.config_path, dotconfig)\n            build.make(self._build_dir, extra_args='-C %s olddefconfig' %\n                       self._build_dir)\n        else:\n            if isinstance(targets, list):\n                _targets = \" \".join(targets)\n            else:\n                _targets = targets\n            build.make(self.build_dir,\n                       extra_args='-C %s %s' % (self.build_dir, _targets))\n        if extra_configs:\n            with tempfile.NamedTemporaryFile(mode='w+t',\n                                             prefix='avocado_') as config_file:\n                config_file.write('\\n'.join(extra_configs))\n                config_file.flush()\n                cmd = ['cd', self._build_dir, '&&',\n                       './scripts/kconfig/merge_config.sh', '.config',\n                       config_file.name]\n                process.run(\" \".join(cmd), shell=True)\n\n    def build(self, binary_package=False, njobs=multiprocessing.cpu_count()):\n        \"\"\"\n        Build kernel from source.\n\n        :param binary_package: when True, the appropriate\n                                  platform package is built\n                                  for install() to use\n        :type binary_pacakge: bool\n        :param njobs: number of jobs. It is mapped to the -j option from make.\n                      If njobs is None then do not limit the number of jobs\n                      (e.g. uses -j without value). The -j is omitted if a\n                      value equal or less than zero is passed. Default value\n                      is set to `multiprocessing.cpu_count()`.\n        :type njobs: int or None\n        \"\"\"\n        make_args = []\n        LOG.info(\"Starting build the kernel\")\n\n        if njobs is None:\n            make_args.append('-j')\n        elif njobs > 0:\n            make_args.extend(['-j', str(njobs)])\n        make_args.extend(['-C', self._build_dir])\n\n        if binary_package is True:\n            if self.distro.name == \"Ubuntu\":\n                make_args.append(\"deb-pkg\")\n\n        build.make(self._build_dir, extra_args=\" \".join(make_args))\n\n    def install(self):\n        \"\"\"\n        Install built kernel.\n        \"\"\"\n        LOG.info(\"Starting kernel install\")\n        if self.distro.name == \"Ubuntu\":\n            process.run('dpkg -i %s/*.deb' %\n                        self.work_dir, shell=True, sudo=True)\n        else:\n            LOG.info(\"Skipping kernel install\")\n\n    def __del__(self):\n        shutil.rmtree(self.work_dir)\n\n\ndef check_version(version):\n    \"\"\"\n    This utility function compares the current kernel version with\n    the version parameter and gives assertion error if the version\n    parameter is greater.\n\n    :type version: string\n    :param version: version to be compared with current kernel version\n    \"\"\"\n    os_version = packaging.version.parse(os.uname()[2])\n    version = packaging.version.parse(version)\n    assert os_version > version, \"Old kernel\"", "path": "avocado/utils/kernel.py"}]}