We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
UnboundLocalError: local variable 'distutils' referenced before assignment
This error happens building from source in Linux. Introduced in https://github.com/pytorch/pytorch/pull/3993

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/setup_helpers/ninja_builder.py`
Content:
```
1 import re
2 import os
3 import sys
4 import setuptools
5 import distutils
6 from contextlib import contextmanager
7 import subprocess
8 
9 BUILD_DIR = 'build'
10 
11 
12 # on the fly create a ninja file in build/ and then
13 # run it when run() is called.
14 class NinjaBuilder(object):
15     def __init__(self, name):
16         import ninja
17         if not os.path.exists(BUILD_DIR):
18             os.mkdir(BUILD_DIR)
19         self.ninja_program = os.path.join(ninja.BIN_DIR, 'ninja')
20         self.name = name
21         self.filename = os.path.join(BUILD_DIR, 'build.{}.ninja'.format(name))
22         self.writer = ninja.Writer(open(self.filename, 'w'))
23         self.writer.rule('do_cmd', '$cmd')
24         self.writer.rule('compile', '$cmd')
25         self.compdb_targets = []
26 
27     def run(self):
28         import ninja
29         self.writer.close()
30         try:
31             subprocess.check_call([self.ninja_program, '-f', self.filename])
32         except subprocess.CalledProcessError as err:
33             # avoid printing the setup.py stack trace because it obscures the
34             # C++ errors.
35             sys.stderr.write(str(err) + '\n')
36             sys.exit(1)
37         compile_db_path = os.path.join(BUILD_DIR, '{}_compile_commands.json'.format(self.name))
38         with open(compile_db_path, 'w') as compile_db:
39             subprocess.check_call([self.ninja_program, '-f', self.filename,
40                                    '-t', 'compdb', 'compile'], stdout=compile_db)
41 
42         # weird build logic in build develop causes some things to be run
43         # twice so make sure even after we run the command we still
44         # reset this to a valid state
45         # don't use the same name or you can't inspect the real ninja files
46         self.__init__(self.name + "_")
47 
48 
49 class ninja_build_ext(setuptools.command.build_ext.build_ext):
50     def _build_default(self, ext):
51         return setuptools.command.build_ext.build_ext.build_extension(self, ext)
52 
53     def build_extension(self, ext):
54         builder = NinjaBuilder(ext.name)
55 
56         @contextmanager
57         def patch(obj, attr_name, val):
58             orig_val = getattr(obj, attr_name)
59             setattr(obj, attr_name, val)
60             try:
61                 yield
62             finally:
63                 setattr(obj, attr_name, orig_val)
64 
65         if self.compiler.compiler_type == 'msvc':
66             import distutils.msvccompiler
67             import distutils.msvc9compiler
68             if sys.version[0] == 2:
69                 orig_compiler = distutils.msvc9compiler.MSVCCompiler
70             else:
71                 orig_compiler = distutils._msvccompiler.MSVCCompiler
72             orig_compile = orig_compiler.compile
73             orig_link = orig_compiler.link
74             orig_spawn = orig_compiler.spawn
75         else:
76             orig_compiler = distutils.unixccompiler.UnixCCompiler
77             orig_compile = orig_compiler._compile
78             orig_link = orig_compiler.link
79 
80         def win_compile(self, sources,
81                         output_dir=None, macros=None, include_dirs=None, debug=0,
82                         extra_preargs=None, extra_postargs=None, depends=None):
83 
84             def spawn(cmd):
85                 # Using regex to match src and obj
86 
87                 src_regex = re.compile('/T(p|c)(.*)')
88                 src_list = [m.group(2) for m in (
89                     src_regex.match(elem) for elem in cmd) if m]
90 
91                 obj_regex = re.compile('/Fo(.*)')
92                 obj_list = [m.group(1) for m in (
93                     obj_regex.match(elem) for elem in cmd) if m]
94 
95                 if len(src_list) >= 1 and len(obj_list) >= 1:
96                     src = src_list[0]
97                     obj = obj_list[0]
98                 else:
99                     # Cannot find src or obj, revert back to original style
100                     return orig_spawn(cmd)
101 
102                 builder.writer.build(
103                     [obj], 'compile', [src],
104                     variables={
105                         'cmd': cmd,
106                         'deps': 'msvc'
107                     })
108 
109             with patch(self, 'spawn', spawn):
110                 orig_compile(self, sources,
111                              output_dir, macros, include_dirs, debug,
112                              extra_preargs, extra_postargs, depends)
113 
114         def unix_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
115             depfile = os.path.splitext(obj)[0] + '.d'
116 
117             def spawn(cmd):
118                 builder.writer.build(
119                     [obj], 'compile', [src],
120                     variables={
121                         'cmd': cmd,
122                         'depfile': depfile,
123                         'deps': 'gcc'
124                     })
125 
126             extra_postargs = extra_postargs + ['-MMD', '-MF', depfile]
127             with patch(self, 'spawn', spawn):
128                 orig_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts)
129 
130         def link(self, target_desc, objects,
131                  output_filename, output_dir=None, libraries=None,
132                  library_dirs=None, runtime_library_dirs=None,
133                  export_symbols=None, debug=0, extra_preargs=None,
134                  extra_postargs=None, build_temp=None, target_lang=None):
135 
136             builder.run()
137             orig_link(self, target_desc, objects,
138                       output_filename, output_dir, libraries,
139                       library_dirs, runtime_library_dirs,
140                       export_symbols, debug, extra_preargs,
141                       extra_postargs, build_temp, target_lang)
142 
143         if self.compiler.compiler_type == 'msvc':
144             _compile_func = win_compile
145             _compile_func_name = 'compile'
146         else:
147             _compile_func = unix_compile
148             _compile_func_name = '_compile'
149 
150         with patch(orig_compiler, _compile_func_name, _compile_func):
151             with patch(orig_compiler, 'link', link):
152                 with patch(self, 'force', True):
153                     self._build_default(ext)
154
```
--- 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/tools/setup_helpers/ninja_builder.py b/tools/setup_helpers/ninja_builder.py
--- a/tools/setup_helpers/ninja_builder.py
+++ b/tools/setup_helpers/ninja_builder.py
@@ -73,6 +73,7 @@
             orig_link = orig_compiler.link
             orig_spawn = orig_compiler.spawn
         else:
+            import distutils.unixccompiler
             orig_compiler = distutils.unixccompiler.UnixCCompiler
             orig_compile = orig_compiler._compile
             orig_link = orig_compiler.link

{"golden_diff": "diff --git a/tools/setup_helpers/ninja_builder.py b/tools/setup_helpers/ninja_builder.py\n--- a/tools/setup_helpers/ninja_builder.py\n+++ b/tools/setup_helpers/ninja_builder.py\n@@ -73,6 +73,7 @@\n             orig_link = orig_compiler.link\n             orig_spawn = orig_compiler.spawn\n         else:\n+            import distutils.unixccompiler\n             orig_compiler = distutils.unixccompiler.UnixCCompiler\n             orig_compile = orig_compiler._compile\n             orig_link = orig_compiler.link\n", "issue": "UnboundLocalError: local variable 'distutils' referenced before assignment\nThis error happens building from source in Linux. Introduced in https://github.com/pytorch/pytorch/pull/3993\n", "before_files": [{"content": "import re\nimport os\nimport sys\nimport setuptools\nimport distutils\nfrom contextlib import contextmanager\nimport subprocess\n\nBUILD_DIR = 'build'\n\n\n# on the fly create a ninja file in build/ and then\n# run it when run() is called.\nclass NinjaBuilder(object):\n    def __init__(self, name):\n        import ninja\n        if not os.path.exists(BUILD_DIR):\n            os.mkdir(BUILD_DIR)\n        self.ninja_program = os.path.join(ninja.BIN_DIR, 'ninja')\n        self.name = name\n        self.filename = os.path.join(BUILD_DIR, 'build.{}.ninja'.format(name))\n        self.writer = ninja.Writer(open(self.filename, 'w'))\n        self.writer.rule('do_cmd', '$cmd')\n        self.writer.rule('compile', '$cmd')\n        self.compdb_targets = []\n\n    def run(self):\n        import ninja\n        self.writer.close()\n        try:\n            subprocess.check_call([self.ninja_program, '-f', self.filename])\n        except subprocess.CalledProcessError as err:\n            # avoid printing the setup.py stack trace because it obscures the\n            # C++ errors.\n            sys.stderr.write(str(err) + '\\n')\n            sys.exit(1)\n        compile_db_path = os.path.join(BUILD_DIR, '{}_compile_commands.json'.format(self.name))\n        with open(compile_db_path, 'w') as compile_db:\n            subprocess.check_call([self.ninja_program, '-f', self.filename,\n                                   '-t', 'compdb', 'compile'], stdout=compile_db)\n\n        # weird build logic in build develop causes some things to be run\n        # twice so make sure even after we run the command we still\n        # reset this to a valid state\n        # don't use the same name or you can't inspect the real ninja files\n        self.__init__(self.name + \"_\")\n\n\nclass ninja_build_ext(setuptools.command.build_ext.build_ext):\n    def _build_default(self, ext):\n        return setuptools.command.build_ext.build_ext.build_extension(self, ext)\n\n    def build_extension(self, ext):\n        builder = NinjaBuilder(ext.name)\n\n        @contextmanager\n        def patch(obj, attr_name, val):\n            orig_val = getattr(obj, attr_name)\n            setattr(obj, attr_name, val)\n            try:\n                yield\n            finally:\n                setattr(obj, attr_name, orig_val)\n\n        if self.compiler.compiler_type == 'msvc':\n            import distutils.msvccompiler\n            import distutils.msvc9compiler\n            if sys.version[0] == 2:\n                orig_compiler = distutils.msvc9compiler.MSVCCompiler\n            else:\n                orig_compiler = distutils._msvccompiler.MSVCCompiler\n            orig_compile = orig_compiler.compile\n            orig_link = orig_compiler.link\n            orig_spawn = orig_compiler.spawn\n        else:\n            orig_compiler = distutils.unixccompiler.UnixCCompiler\n            orig_compile = orig_compiler._compile\n            orig_link = orig_compiler.link\n\n        def win_compile(self, sources,\n                        output_dir=None, macros=None, include_dirs=None, debug=0,\n                        extra_preargs=None, extra_postargs=None, depends=None):\n\n            def spawn(cmd):\n                # Using regex to match src and obj\n\n                src_regex = re.compile('/T(p|c)(.*)')\n                src_list = [m.group(2) for m in (\n                    src_regex.match(elem) for elem in cmd) if m]\n\n                obj_regex = re.compile('/Fo(.*)')\n                obj_list = [m.group(1) for m in (\n                    obj_regex.match(elem) for elem in cmd) if m]\n\n                if len(src_list) >= 1 and len(obj_list) >= 1:\n                    src = src_list[0]\n                    obj = obj_list[0]\n                else:\n                    # Cannot find src or obj, revert back to original style\n                    return orig_spawn(cmd)\n\n                builder.writer.build(\n                    [obj], 'compile', [src],\n                    variables={\n                        'cmd': cmd,\n                        'deps': 'msvc'\n                    })\n\n            with patch(self, 'spawn', spawn):\n                orig_compile(self, sources,\n                             output_dir, macros, include_dirs, debug,\n                             extra_preargs, extra_postargs, depends)\n\n        def unix_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):\n            depfile = os.path.splitext(obj)[0] + '.d'\n\n            def spawn(cmd):\n                builder.writer.build(\n                    [obj], 'compile', [src],\n                    variables={\n                        'cmd': cmd,\n                        'depfile': depfile,\n                        'deps': 'gcc'\n                    })\n\n            extra_postargs = extra_postargs + ['-MMD', '-MF', depfile]\n            with patch(self, 'spawn', spawn):\n                orig_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts)\n\n        def link(self, target_desc, objects,\n                 output_filename, output_dir=None, libraries=None,\n                 library_dirs=None, runtime_library_dirs=None,\n                 export_symbols=None, debug=0, extra_preargs=None,\n                 extra_postargs=None, build_temp=None, target_lang=None):\n\n            builder.run()\n            orig_link(self, target_desc, objects,\n                      output_filename, output_dir, libraries,\n                      library_dirs, runtime_library_dirs,\n                      export_symbols, debug, extra_preargs,\n                      extra_postargs, build_temp, target_lang)\n\n        if self.compiler.compiler_type == 'msvc':\n            _compile_func = win_compile\n            _compile_func_name = 'compile'\n        else:\n            _compile_func = unix_compile\n            _compile_func_name = '_compile'\n\n        with patch(orig_compiler, _compile_func_name, _compile_func):\n            with patch(orig_compiler, 'link', link):\n                with patch(self, 'force', True):\n                    self._build_default(ext)\n", "path": "tools/setup_helpers/ninja_builder.py"}], "after_files": [{"content": "import re\nimport os\nimport sys\nimport setuptools\nimport distutils\nfrom contextlib import contextmanager\nimport subprocess\n\nBUILD_DIR = 'build'\n\n\n# on the fly create a ninja file in build/ and then\n# run it when run() is called.\nclass NinjaBuilder(object):\n    def __init__(self, name):\n        import ninja\n        if not os.path.exists(BUILD_DIR):\n            os.mkdir(BUILD_DIR)\n        self.ninja_program = os.path.join(ninja.BIN_DIR, 'ninja')\n        self.name = name\n        self.filename = os.path.join(BUILD_DIR, 'build.{}.ninja'.format(name))\n        self.writer = ninja.Writer(open(self.filename, 'w'))\n        self.writer.rule('do_cmd', '$cmd')\n        self.writer.rule('compile', '$cmd')\n        self.compdb_targets = []\n\n    def run(self):\n        import ninja\n        self.writer.close()\n        try:\n            subprocess.check_call([self.ninja_program, '-f', self.filename])\n        except subprocess.CalledProcessError as err:\n            # avoid printing the setup.py stack trace because it obscures the\n            # C++ errors.\n            sys.stderr.write(str(err) + '\\n')\n            sys.exit(1)\n        compile_db_path = os.path.join(BUILD_DIR, '{}_compile_commands.json'.format(self.name))\n        with open(compile_db_path, 'w') as compile_db:\n            subprocess.check_call([self.ninja_program, '-f', self.filename,\n                                   '-t', 'compdb', 'compile'], stdout=compile_db)\n\n        # weird build logic in build develop causes some things to be run\n        # twice so make sure even after we run the command we still\n        # reset this to a valid state\n        # don't use the same name or you can't inspect the real ninja files\n        self.__init__(self.name + \"_\")\n\n\nclass ninja_build_ext(setuptools.command.build_ext.build_ext):\n    def _build_default(self, ext):\n        return setuptools.command.build_ext.build_ext.build_extension(self, ext)\n\n    def build_extension(self, ext):\n        builder = NinjaBuilder(ext.name)\n\n        @contextmanager\n        def patch(obj, attr_name, val):\n            orig_val = getattr(obj, attr_name)\n            setattr(obj, attr_name, val)\n            try:\n                yield\n            finally:\n                setattr(obj, attr_name, orig_val)\n\n        if self.compiler.compiler_type == 'msvc':\n            import distutils.msvccompiler\n            import distutils.msvc9compiler\n            if sys.version[0] == 2:\n                orig_compiler = distutils.msvc9compiler.MSVCCompiler\n            else:\n                orig_compiler = distutils._msvccompiler.MSVCCompiler\n            orig_compile = orig_compiler.compile\n            orig_link = orig_compiler.link\n            orig_spawn = orig_compiler.spawn\n        else:\n            import distutils.unixccompiler\n            orig_compiler = distutils.unixccompiler.UnixCCompiler\n            orig_compile = orig_compiler._compile\n            orig_link = orig_compiler.link\n\n        def win_compile(self, sources,\n                        output_dir=None, macros=None, include_dirs=None, debug=0,\n                        extra_preargs=None, extra_postargs=None, depends=None):\n\n            def spawn(cmd):\n                # Using regex to match src and obj\n\n                src_regex = re.compile('/T(p|c)(.*)')\n                src_list = [m.group(2) for m in (\n                    src_regex.match(elem) for elem in cmd) if m]\n\n                obj_regex = re.compile('/Fo(.*)')\n                obj_list = [m.group(1) for m in (\n                    obj_regex.match(elem) for elem in cmd) if m]\n\n                if len(src_list) >= 1 and len(obj_list) >= 1:\n                    src = src_list[0]\n                    obj = obj_list[0]\n                else:\n                    # Cannot find src or obj, revert back to original style\n                    return orig_spawn(cmd)\n\n                builder.writer.build(\n                    [obj], 'compile', [src],\n                    variables={\n                        'cmd': cmd,\n                        'deps': 'msvc'\n                    })\n\n            with patch(self, 'spawn', spawn):\n                orig_compile(self, sources,\n                             output_dir, macros, include_dirs, debug,\n                             extra_preargs, extra_postargs, depends)\n\n        def unix_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):\n            depfile = os.path.splitext(obj)[0] + '.d'\n\n            def spawn(cmd):\n                builder.writer.build(\n                    [obj], 'compile', [src],\n                    variables={\n                        'cmd': cmd,\n                        'depfile': depfile,\n                        'deps': 'gcc'\n                    })\n\n            extra_postargs = extra_postargs + ['-MMD', '-MF', depfile]\n            with patch(self, 'spawn', spawn):\n                orig_compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts)\n\n        def link(self, target_desc, objects,\n                 output_filename, output_dir=None, libraries=None,\n                 library_dirs=None, runtime_library_dirs=None,\n                 export_symbols=None, debug=0, extra_preargs=None,\n                 extra_postargs=None, build_temp=None, target_lang=None):\n\n            builder.run()\n            orig_link(self, target_desc, objects,\n                      output_filename, output_dir, libraries,\n                      library_dirs, runtime_library_dirs,\n                      export_symbols, debug, extra_preargs,\n                      extra_postargs, build_temp, target_lang)\n\n        if self.compiler.compiler_type == 'msvc':\n            _compile_func = win_compile\n            _compile_func_name = 'compile'\n        else:\n            _compile_func = unix_compile\n            _compile_func_name = '_compile'\n\n        with patch(orig_compiler, _compile_func_name, _compile_func):\n            with patch(orig_compiler, 'link', link):\n                with patch(self, 'force', True):\n                    self._build_default(ext)\n", "path": "tools/setup_helpers/ninja_builder.py"}]}